Inheritance in EntityFramework

3

I have a parent class DadosClientes and two child classes DadosClientesPF , and DadosClientesPJ .

The DadosCliente instance has the field: Nome , Telefone

The instance DadosClientePF has the field: CPF

The instance DadosClientePJ has the field: CNPJ

The client object has a DadosClientes instance, but it only accesses the DadosCliente fields, how do I access the CPF and CNPJ ? fields

    
asked by anonymous 07.04.2015 / 15:49

3 answers

4

If you want to get a property, you have to instantiate a class that has this property. So if you want CPF , you need to instantiate DadosCLientesPF . If you instantiate DadosClientes you can not get the CPF simply because it does not exist in this class.

If you are using a method that receives DadosClientes and needs to access something that is not available in it, you are doing something wrong as well. In this case the correct would be to have separate methods to deal with DadosClientesPF , with DadosCLientesPJ and maybe even keep what it deals with only DadosClientes if it is useful, which I doubt.

I especially do not like the solution given in the other answer. I'm not a purist but that's not object-oriented programming. Methods should not have to know how to deal with derived objects of the type expected. When this is necessary, specialized methods must be created, otherwise if it is then created ClientesDadosEstrangeiro would have to tinker with the implementation of this method. Depending on the scenario it may not be problematic but in others it may be. I do not know if you need to use inheritance in this case, but if you will use it, do it for the right reasons, and use it the right way.

If you have separated into two classes, treat them as different things. If the intention is to treat it as if it were the same thing, do not separate it.

But if your problem is polymorphism (not that it is the case), that is, you are instantiating the derived class but when you pass it to some method that expects the base class, then your problem is that property must be virtual . This guarantees the polymorphism and will call the property correctly, since it will interpret the object with its type originally instantiated and not by the type concretely declared in the parameter of the method. Of course this only applies if the property exists in the base class.

You may need to re-evaluate your entire modeling .

    
07.04.2015 / 16:36
4

After loading the object cliente of the DB, you can check the type of the property.

Example using the as operator:

using (var context = new Context())
{
    var cli = context.Clientes.Where(c => c.Id == idCli).Single();
    var pf = cli.DadosClientes as DadosClientePF;
    if (pf != null)
    {
        // pessoa física
        var cpf = pf.CPF;
    }

    var pj = cli.DadosClientes as DadosClientePJ;
    if (pj != null)
    {
        // pessoa jurídica
        var cnpj = pj.CNPJ;
    }
}

To create a new client, simply create one of the DadosClientePF or DadosClientePJ classes and assign it to the cli.DadosClientes property:

using (var context = new Context())
{
    var cli = new Cliente();
    if (cnpj != null)
    {
        cli.DadosClientes = new DadosClientePJ
            {
                CNPJ = cnpj
            };
    }

    if (cpf != null)
    {
        cli.DadosClientes = new DadosClientePF
            {
                CPF = cpf
            };
    }

    if (cli.DadosClientes != null)
        cli.DadosClientes.Nome = nome;

    context.Clientes.Add(cli);
    context .SaveChanges();
}
    
07.04.2015 / 17:34
1

Assuming you have:

class DadosCliente
{
  public string Nome { get; set; }
  public string Telefone { get; set; }
}

class DadosClientePF : DadosCliente
{
  public string CPF { get; set; }
}

class DadosClientePJ : DadosCliente
{
  public string CNPJ { get; set; }
}

And instantiate a PF object:

DadosClientePF obj = new DadosClientePF{
  Nome = 'Nome',
  CPF = '000.000.000-00'
};

And then it executes a method that receives a parameter of type Customer Data:

void Testar(DadosCliente dados)

To access the properties of the child classes in this method you need to check the instance type and cast:

if (dados is DadosClientePJ)
{
    DadosClientePJ dadosPj = (DadosClientePJ)dados;
    Console.Write(dadosPj.CNPJ);
}
else if (dados is DadosClientePF)
{
    DadosClientePF dadosPf = (DadosClientePF)dados;
    Console.Write(dadosPf.CPF);
}
    
07.04.2015 / 16:07