.NET

13 jul, 2011

Partial Class com Entity Framework

Publicidade

Olá, pessoal!

Hoje veremos um recurso que acho muito interessante no .NET, a Partial Class.

Partial Class é uma forma de dividir a definição de uma class em mais de um único arquivo físico. Porém, ao compilar nossa class, o compilador irá interpretar como se fosse uma única class.

Antes de explicar a utilização de Partial Class com Entity Framework, vou explicar o que é Partial Class na prática.

Primeiramente, vamos criar um projeto no Visual Studio do tipo Console Application. Depois nomeie como ConsolePartialClass.

Em seguida, crie uma class e chame o arquivo de Pessoa, depois coloque as seguintes propriedades:

public class Pessoa {

public int intCodigoPessoa { get; set; }

public string strNomePessoa { get; set; }

}

Agora crie uma segunda class e chame o arquivo de PessoaJuridica, mas a class chame de pessoa conforme podemos ver abaixo:

public partial class Pessoa {

public string strNomeFantasia { get; set; }

}

Note que utilizamos a palavra partial antes da palavra class para informar ao compilador que essa class faz uma união com a class Pessoa.

Agora acesse o arquivo Program e instancie a class Pessoa. Você poderá ter acesso as três propriedades que criamos. Veja:

Esse foi apenas um exemplo simples de como utilizar. Uma forma legal é criar dois arquivos físicos, separar as propriedades em um arquivo e os métodos em outro arquivo.

Existem algumas regras a serem observadas:

  • As classes partial não podem ter modificadores de acesso diferentes;
  • A classe principal e as que recebem o partial têm que estar na mesma namespace;
  • Quando algo estiver definido em uma das classes, essa definição estará disponível para as demais classes.

Caso tenha alguma dúvida sobe partial class ou queira aumentar seu conhecimento, acesse esse artigo no site do MSDN.

Vamos utilizar Partial Class com Entity Framework.

Para esse exemplo, criei três tabelas em uma base de dados SQL Server, como o script  abaixo:

CREATE TABLE [dbo].[UF]( [CD_UF] [nchar](2) NOT NULL, 
[DS_UF] [nchar](10) NULL,
CONSTRAINT [PK_UF] PRIMARY KEY CLUSTERED( [CD_UF] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY]) ON [PRIMARY]
GO
CREATE TABLE [dbo].[MUNICIPIO]( [CD_MUNICIPIO] [numeric](10, 0) NOT NULL,
[NM_MUNICIPIO] [varchar](100) NULL,
[CD_UF] [nchar](2) NULL,
CONSTRAINT [PK_MUNICIPIO] PRIMARY KEY CLUSTERED( [CD_MUNICIPIO] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_PADDING OFFGO
ALTER TABLE [dbo].[MUNICIPIO] WITH CHECK ADD CONSTRAINT [FK_MUNICIPIO_UF]
FOREIGN KEY([CD_UF])REFERENCES [dbo].[UF] ([CD_UF])
GO
ALTER TABLE [dbo].[MUNICIPIO] CHECK CONSTRAINT [FK_MUNICIPIO_UF]
GO
CREATE TABLE [dbo].[PESSOA]( [CD_PESSOA] [numeric](10, 0) NOT NULL,
[NM_PESSOA] [varchar](100) NULL,
[CD_MUNICIPIO] [numeric](10, 0) NULL,
CONSTRAINT [PESSOA_PK] PRIMARY KEY CLUSTERED( [CD_PESSOA] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_PADDING OFFGO
ALTER TABLE [dbo].[PESSOA] WITH CHECK ADD CONSTRAINT [PESSOA_MUNICIPIO_FK]
FOREIGN KEY([CD_MUNICIPIO])REFERENCES [dbo].[MUNICIPIO] ([CD_MUNICIPIO])
GO
ALTER TABLE [dbo].[PESSOA] CHECK CONSTRAINT [PESSOA_MUNICIPIO_FK]
GO

Insira alguns valores nessa tabela para utilizarmos em nosso exemplo.

Depois de ter os valores preenchidos, abra o Visual Studio e crie um projeto do tipo Library Class em C#, e nomeie o projeto como PartialClassWithEntity. Em seguida, clique com o botão direito sobre o projeto em Add New Item e selecione ADO.NET Entity Data Model. Chame o arquivo de Partial.edmx.

Em Entity Data Model, selecione Generate from database e clique em next. Na próxima tela, você selecionará a conexão com a base de dados que criamos nossas tabelas anteriormente. Talvez seja necessário que você crie a conexão.

Com a conexão criada, marque a opção Yes, include the sensitive data in the connection string e a opção Save entity connection settings in App.Config as, e em seguida coloque um nome para sua conexão entity – nesse caso está PartialEntity, e clique em next.

Na próxima tela, selecione as três tabelas que criamos anteriormente e clique em Finish, para que as entidades sejam criadas conforme a imagem abaixo:

Com o projeto Library pronto, vamos adicionar outro projeto à solução. Clique na Solution e em Add New Project.

Selecione um projeto do Tipo Console em C# com o nome de ConsolePartial. Com o projeto criado, clique com o botão direito sobre ele e em Add Reference selecione a guia Projects e o projeto PartialClassWithEntity que possui o Entity Framework.

Volte em Add New Reference, mas selecione a guia NET e em seguida selecione a biblioteca System.Data.Entity. Também copie o arquivo App.config do projeto PartialClassWithFramework para o projeto ConsolePartial. Lembre-se de copiar e não recortar.

No arquivo Program.cs, escreva o seguinte código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PartialClassWithEntity;

namespace ConsolePartial
{
class Program

{

static void Main(string[] args)
{
using (PartialEntity ef = new PartialEntity())
{
IQueryable iqbPessoa = from p in ef.PESSOA select p;

foreach (PESSOA p in iqbPessoa)
{
Console.WriteLine(string.Format("Nome Pessoa: {0} - Município/UF: {1}", p.NM_PESSOA, p.MUNICIPIO.NM_MUNICIPIO));
}
}

Console.Read();
}
}
}

Executando o código será possível visualizar os dados que inserimos na tabela PESSOA. Veja que não conseguimos trazer a descrição da UNIDADE FEDERATIVA (UF). É claro que podemos concatenar a descrição da unidade federativa, como no exemplo abaixo:

Console.WriteLine(string.Format("Nome Pessoa: {0} - Município/UF: {1} - {2}", p.NM_PESSOA, p.MUNICIPIO.NM_MUNICIPIO, p.MUNICIPIO.UF.DS_UF));

Mas e se a entidade PESSOA já tivesse uma propriedade com o nome do município relacionado com o nome da unidade federativa?

Volte ao projeto PartialClassWithEntity (nosso projeto Library) e crie uma nova class chamada PESSOA. A classe deve ser criada conforme abaixo:

ususing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PartialClassWithEntity
{
public partial class PESSOA
{
public string NM_MUNICIPOUF
{
get { return MUNICIPIO.NM_MUNICIPIO + " - " + MUNICIPIO.UF.DS_UF; }
}
}
}

Veja que criamos uma propriedade chamada NM_MUNICIPIOUF, que quando realizamos o get, ele concatena os campos NM_MUNICIPIO E DS_UF. Compile o projeto class e altere o projeto console com a linha abaixo:

Console.WriteLine(string.Format("Nome Pessoa: {0} - Município/UF: {1}", p.NM_PESSOA, p.NM_MUNICIPOUF));

Através da Partial Class criamos uma nova propriedade para nossa class do Entity Framework, sendo que essa propriedade não faz relação com nenhuma coluna da tabela PESSOA. Podemos criar outras propriedades que podem ser úteis, utilizando Partial em várias vezes do projeto com EF.

Lembre que a Class Partial deve estar na mesma namespace da classe principal, senão o compilador vai entender como sendo duas classes diferentes.

Outro detalhe importante: veja que o foreach está dentro do Using, porque para que nossa propriedade NM_MUNICIPOUF seja populada, o Entity precisa estar aberto. E ccaso ele esteja fechado, um exception irá acontecer. Veja abaixo a maneira de como o código não irá funcionar.

static void Main(string[] args)
{
IQueryable<PESSOA> iqbPessoa = null;

using (PartialEntity ef = new PartialEntity())
{

iqbPessoa = from p in ef.PESSOA select p;

}

foreach (PESSOA p in iqbPessoa)
{
Console.WriteLine(string.Format("Nome Pessoa: {0} - Município/UF: {1}", p.NM_PESSOA, p.NM_MUNICIPOUF));
}

Console.Read();
}

Executando o código acima, uma exception (The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.) será exibida.

Espero que esse exemplo seja útil. Compartilhe seus experimentos e deixe seu recado nos comentários.

Obrigado pela atenção e até a próxima!