1
I have two entities that inherit from the same abstract class.
public class Empresa : PessoaJuridica
{
private Empresa()
{
}
public Empresa(string CNPJ, string RazaoSocial, Status Situacao, byte MaxNumeroUsuarios)
{
base.CNPJ = CNPJ;
base.RazaoSocial = RazaoSocial;
base.Situacao = Situacao;
//.. simplificado para facilitar
}
//.. simplificado para facilitar
}
The other class
public class ClientePJ : PessoaJuridica
{
private long _empresa_id;
private ClientePJ()
{
}
public ClientePJ(long IdEmpresa, string CNPJ, string RazaoSocial, Status Situacao)
{
this.Empresa_Id = IdEmpresa;
base.CNPJ = CNPJ;
base.RazaoSocial = RazaoSocial;
base.Situacao = Situacao;
//.. simplificado para facilitar
}
//.. simplificado para facilitar
}
The abstract class
public abstract class PessoaJuridica : EntidadeBase, IDataCadastro, IDataUltimaModificacao, INaoExcluivel
{
public string NomeFantasia { get; set; }
public string RazaoSocial { get; set; }
public string CNPJ { get; set; }
public Status Situacao { get; set; }
public string Website { get; set; }
public DateTime? DataCadastro { get; set; }
public DateTime? DataUltimaModificacao { get; set; }
public long IdLoginCadastro { get; set; }
public long? IdLoginUltimaModificacao { get; set; }
public Endereco Endereco { get; set; }
public ICollection<Contato> Contatos { get; set; }
}
All 3 classes are mapped in the Entity Framework separately
public PessoaJuridicaMap()
{
HasKey(pj => pj.Id);
Property(pj => pj.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(pj => pj.NomeFantasia).HasMaxLength(255);
Property(pj => pj.RazaoSocial).IsRequired().HasMaxLength(255);
Property(pj => pj.Situacao).HasColumnName("Status").IsRequired();
Property(pj => pj.CNPJ).IsRequired().IsFixedLength().HasMaxLength(14);
Property(pj => pj.Website).HasMaxLength(255);
Property(pj => pj.DataCadastro).IsRequired();
Property(pj => pj.IdLoginCadastro).IsRequired();
HasMany(pj => pj.Contatos).WithMany().Map(m => {
m.ToTable("PessoasJuridicas_Contatos", "Admin");
m.MapLeftKey("PessoaJuridica_Id");
m.MapRightKey("Contato_Id");
});
HasOptional(pj => pj.Endereco);
ToTable("PessoasJuridicas", "Base");
}
//
public EmpresaMap()
{
HasKey(e => e.Id);
Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(e => e.Situacao).HasColumnName("Status").IsRequired();
Property(e => e.MaxNumeroUsuarios).IsRequired();
Property(e => e.DataCadastro).IsRequired();
ToTable("Empresas", "Admin");
}
//
public ClientePJMap() {
HasKey(cpj => cpj.Id);
Property(cpj => cpj.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(cpj => cpj.Empresa_Id).IsRequired();
ToTable("ClientesPJ", "Clientes");
}
I use a generic repository for all classes, as below
public RepositorioBase(D contexto)
{
this.conexao = contexto;
}
#endregion
#region Métodos do Repositorio
public void Salvar(T entidade)
{
conexao.Entry(entidade).State = EntityState.Added;
}
public T BuscarPorId(long? id)
{
return conexao.Set<T>().Find(id);
}
public ICollection<T> BuscarTodos()
{
ICollection<T> lista = conexao.Set<T>().ToList();
return (lista.Count == 0) ? null : lista;
}
public T FiltrarUmPor(Func<T, bool> predicado)
{
return conexao.Set<T>().Where(predicado).Single();
}
public ICollection<T> FiltrarVariosPor(Func<T, bool> predicado)
{
return conexao.Set<T>().Where(predicado).ToList();
}
My test suite has the following tests
[TestMethod]
[Description("Busca todos os Clientes")]
[TestCategory("Testes de repositorio")]
public void BuscarTodosClientes()
{
ICollection<ClientePJ> lista = repositorioCliente.BuscarTodos();
Assert.IsNotNull(lista);
}
[TestMethod]
[Description("Busca cliente por Id")]
[TestCategory("Testes de repositorio")]
public void BuscarClientePorId()
{
ClientePJ cliente = repositorioCliente.BuscarPorId(1);
Assert.IsNotNull(cliente);
}
I have similar tests for all repositories and all run perfect, but when I get to the above test of Buscarclienteporid, I take the following cast error:
System.Invalidoperationexception: The specified cast from a materialized 'Dominio.Entidades.Empresa' type to the 'Dominio.Entidades.Clientepj' type is not Valid.
I don’t know what’s going on since the search for all the ClientePJ
works and does not give error, and is pointing to the same repository.
Has anyone ever seen this?
Try to change
ClientePJ cliente = repositorioCliente.BuscarPorId(1);
forvar cliente = db.ClientesPJ.FirstOrDefault(c => c.Empresa_Id == 1)
. What happens?– Leonel Sanches da Silva
I was bumping my head here and I found out, actually Id 1 belongs to a Personal Corporation that points to a Company, not to a Clientepj, so EF was doing the 'wrong' cast. I’ll change the test to get a random Clientepj ID.
– Paulo Weber