Consulta Linq para unir 2 tabelas que simula herança.

27/02/2015

Olá a todos do fórum, estou estudando o Entity Framework 6 Code-First e estou com uma dúvida se como eu fiz está correto na questão da herança;

#Classe Pessoa
public class Pessoa
{
public int Pessoa_Id { get; set; }
public DateTime DTCadastro { get; set; }
public string NomeRazao { get; set; }
}

#Classe PessoaFisica
public class PessoaFisica : Pessoa
{
public string Cpf { get; set; }
}

#Classe PessoaJuridica
public class PessoaJuridica : Pessoa
{
public string Cnpj { get; set; }
}

#Meu contexto
public class Context : DbContext
{
public Context() : base ("MySQL")
{

}
public DbSet<Empresa> Empresas { get; set; }
public DbSet<Pessoa> Pessoas { get; set; }
public DbSet<PessoaFisica> PessoasFisicas { get; set; }
public DbSet<PessoaJuridica> PessoasJuridicas { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
#region Empresa

modelBuilder.Entity<Empresa>().ToTable("empresa")
.HasKey(e => e.Empresa_Id);

modelBuilder.Entity<Empresa>()
.Property(e => e.DTCadastro)
.HasColumnType("date");

modelBuilder.Entity<Empresa>()
.Property(e => e.Razao)
.HasMaxLength(50)
.IsRequired();

modelBuilder.Entity<Empresa>()
.Property(e => e.Cnpj)
.HasMaxLength(14)
.IsRequired();

modelBuilder.Entity<Empresa>()
.Property(e => e.Ie)
.HasMaxLength(20)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.IM)
.HasMaxLength(20)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.TelFixo)
.HasMaxLength(11)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.TelCelular)
.HasMaxLength(11)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.Email)
.HasMaxLength(50)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.HomePage)
.HasMaxLength(50)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.Endereco)
.HasMaxLength(50)
.IsRequired();

modelBuilder.Entity<Empresa>()
.Property(e => e.Complemento)
.HasMaxLength(50)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.Bairro)
.HasMaxLength(50)
.IsRequired();

modelBuilder.Entity<Empresa>()
.Property(e => e.Cep)
.HasMaxLength(8)
.IsRequired();

modelBuilder.Entity<Empresa>()
.Property(e => e.Cidade)
.HasMaxLength(50)
.IsRequired();

modelBuilder.Entity<Empresa>()
.Property(e => e.UF)
.HasMaxLength(2)
.IsRequired();

modelBuilder.Entity<Empresa>()
.Property(e => e.Apelido)
.HasMaxLength(20)
.IsRequired();

modelBuilder.Entity<Empresa>()
.Property(e => e.NumeroAtoAnatel)
.HasMaxLength(10)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.NumeroFistel)
.HasMaxLength(15)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.EngenheiroNome)
.HasMaxLength(50)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.EngenheiroTelFixo)
.HasMaxLength(11)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.EngenheiroTelCelular)
.HasMaxLength(20)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.EngenheiroEmail)
.HasMaxLength(50)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.EngenheiroNumCREA)
.HasMaxLength(20)
.IsOptional();

modelBuilder.Entity<Empresa>()
.Property(e => e.EmpresaNumCREA)
.HasMaxLength(20)
.IsOptional();

#endregion Empresa

#region Pessoa

modelBuilder.Entity<Pessoa>().ToTable("pessoa")
.HasKey(p => p.Pessoa_Id);

modelBuilder.Entity<PessoaFisica>().ToTable("pessoafisica")
.HasKey(pf => pf.Pessoa_Id);

modelBuilder.Entity<PessoaFisica>()
.Property(pf => pf.DTCadastro)
.HasColumnType("date")
.IsRequired();

modelBuilder.Entity<PessoaFisica>()
.Property(pf => pf.NomeRazao)
.HasMaxLength(50)
.IsRequired();

modelBuilder.Entity<PessoaFisica>()
.Property(pf => pf.Cpf)
.HasMaxLength(11)
.IsRequired();

modelBuilder.Entity<PessoaJuridica>().ToTable("pessoajuridica")
.HasKey(pj => pj.Pessoa_Id);

modelBuilder.Entity<PessoaJuridica>()
.Property(pj => pj.DTCadastro)
.HasColumnType("date")
.IsRequired();

modelBuilder.Entity<PessoaJuridica>()
.Property(pj => pj.NomeRazao)
.HasMaxLength(50)
.IsRequired();

modelBuilder.Entity<PessoaJuridica>()
.Property(pj => pj.Cnpj)
.HasMaxLength(14)
.IsRequired();

#endregion Pessoa
}
}
}

Quando eu precisar retornar os dados das duas tabelas filhas que no caso são PessoaFisica e PessoaJuridica e usei a seguinte consulta linq. A pergunta é a forma como estou fazendo está correta? Pois em uma tabela com mais de 1000 registros irei ter um bom desempenho ou tem como melhorar isto.

using (var ctx = new Context())
{
var consulta1 = (from p in ctx.Pessoas
join pf in ctx.PessoasFisicas on p.Pessoa_Id equals pf.Pessoa_Id
select new
{
Codigo = p.Pessoa_Id,
Data = p.DTCadastro,
NomeRazao = p.NomeRazao,
CpfCnpj = pf.Cpf
}).ToList();

var consulta2 = (from p in ctx.Pessoas
join pj in ctx.PessoasJuridicas on p.Pessoa_Id equals pj.Pessoa_Id
select new
{
Codigo = p.Pessoa_Id,
Data = p.DTCadastro,
NomeRazao = p.NomeRazao,
CpfCnpj = pj.Cnpj
}).ToList();

var consulta3 = consulta1.Concat(consulta2);


dataGridView1.DataSource = consulta3.ToList();
}

[img:descricao=Exemplo de como ficou o retorno em um DataGridView]http://arquivo.devmedia.com.br/forum/imagem/267760-20150227-113448.png[/img]

Elessandro Poças

Respostas

05/03/2015

Elessandro Poças

Olá a todos,
Estou postando mais uma forma que fiz para fazer a consulta.

O que está consulta está fazendo;

consulta1 = Está unindo as tabelas PessoaFisica e PessoaJuridica e retornando os dados que preciso;
consulta2 = Está fazendo um join na tabela Cliente e retornando PessoaFisica e PessoaJuridica que são clientes.

using (var ctx = new Context())
{
var consulta1 = (from pf in ctx.PessoasFisicas
select new { Codigo = pf.Pessoa_Id, Data = pf.DTCadastro, Nome = pf.NomeRazao, CpfCnpj = pf.Cpf })
.Union(from pj in ctx.PessoasJuridicas
select new { Codigo = pj.Pessoa_Id, Data = pj.DTCadastro, Nome = pj.NomeRazao, CpfCnpj = pj.Cnpj });

var consulta2 = from c in ctx.Clientes
join cli in consulta1 on c.Pessoa_Id equals cli.Codigo
orderby cli.Nome
select new
{
c.Pessoa_Id,
c.NomeRazao,
c.DTCadastro,
cli.CpfCnpj
};

dataGridView1.DataSource = consulta2.ToList();

Gostaria da opinião de vocês sobre a consulta acima, se é desta forma mesmo ou se há uma forma mais correta deste tipo de consulta.
[img]http://arquivo.devmedia.com.br/forum/imagem/267760-20150305-154035.png[/img]
Responder Citar