EF 6, Fluent Api mapping in inheritance classes

Asked

Viewed 2,690 times

4

I am training in class mapping for the Entity Framework using the Fluent API and I have some questions.

The first is as follows: Map a Foreign key with attributes would be like this:

public int EmpresaId {get; set;}
[ForeignKey("EmpresaId")]
public Empresa Empresa {get; set;}

With Fluent API it would be like this:

HasRequired(p => p.Empresa).WithMany().HasForeignKey(p => p.EmpresaId);

Is that correct? What I don’t understand is this WithMany() since it is a simple foreign key connection and is not a ICollection<>, for example. So why WithMany()?

The other question would be, how would the mapping with the Fluent API of these classes, since two inherit from the first?

public class Pessoa
{
    public int Id {get; set;}
    public string Nome {get; set;}
}

public class PessoaFisica : Pessoa
{
    public string CPF {get; set;}
}

public class PessoaJuridica : Pessoa
{
    public string CNPJ {get; set;}
}

2 answers

6


Withmany

Is used WithMany() to specify a Many relationship. What’s really weird is the fact that you’re using WithMany() unencumbered. WithMany() serves for you to specify the inverse relation.

For example, if that chunk of code refers to a person, the correct mapping would be like this:

HasRequired(p => p.Empresa)
    .WithMany(e => e.Pessoas)
    .HasForeignKey(p => p.EmpresaId);

Classe Pessoa

One Pessoa in theory can only be Physical or Legal, right? The correct thing would be to do:

public abstract class Pessoa
{
    public int Id {get; set;}
    public string Nome {get; set;}
}

public class PessoaFisica : Pessoa
{
    public string CPF {get; set;}
}

public class PessoaJuridica : Pessoa
{
    public string CNPJ {get; set;}
}

In the Fluent API:

modelBuilder.Entity<PessoaFisica>()
    .HasKey(pf => pf.Id);
modelBuilder.Entity<PessoaFisica>()
    .Property(pf => pf.Nome)
    .HasMaxLength(70)
    .IsRequired();
modelBuilder.Entity<PessoaJuridica>()
    .HasKey(pj => pj.Id);
modelBuilder.Entity<PessoaJuridica>()
    .Property(pj => pj.Nome)
    .HasMaxLength(70)
    .IsRequired();
  • 1

    Gosh, I don’t even have time to answer you appear here already responding ein... kkk will be active so there in china... joke...

  • Cool your class example abstrata of Pessoa, but as for the property Name, it was seen Fluent API i want to specify that it is required and has a maximum of 70 characters, for example, where I would make this specification?

  • @Tiago I’ll edit the answer for you.

  • @Gypsy omorrisonmendez but he could make one DbSet<Pessoa> and in the modelBuilder.Entity<Pessoa>.Property(p => p.Nome).IsRequired(); He could do the validation, couldn’t he? Descriminator the framework would handle distributing the classes correctly, wouldn’t it? (ps: can’t test now [away from a visual studio/. net PC])

  • @tchicotti Pode. Also worth as an example.

3

James, probably your class must be something like this:

public Pessoa {
    public int Id { get; set; }
    public int EmpresaId {get; set;}
    [ForeignKey("EmpresaId")]
    public Empresa Empresa {get; set;}
}

Hence your Company class should be something around

public Empresa {
    public int Id { get; set; }
    //... 
    public ICollection<Pessoa> Pessoas {get; set;}
}

Am I right, sir? If it is, your Fluent relationship should represent as follows:

modelBuilder.Entity<Pessoa>()
            .HasRequired(p => p.Empresa)
            .WithMany(e => e.Pessoas)
            .HasForeignKey(p => p.EmpresaId);

What happens is this: The person Entity<Pessoa> has a mandatory field (required) HasRequired(p => p.Empresa) which is part of a company list WithMany(e => e.Pessoas);

That is, that person needs to have a company and that person will be linked to the people that exist in that company (ICollection).

  • +1 for the useful and relevant response ;)

  • Yes, that would be the class structure. I believe then that my lack of knowledge was in the part where, since a Person has a connection to a Company, in the company I HAVE TO HAVE a collection of Persons belonging to it. Would this be the right one for mapping to the Entityframework? To clarify, I did not do this ICollection<Pessoa> Pessoas.

  • 1

    That property ICollection<Pessoa> Pessoas is a NavigationProperty so that the Context know what is the relationship between classes

  • @tchicotti, thank you very much!

  • Only, there could be scenarios where I do something like: ctx.Empresas.Include(x=>x.Pessoas); ? I find that very impractical, is not?

  • 1

    The Include serves for when you try to access their properties give Person, do not need to search again in the bank, but the example Icollection<Person> was only to show the existence of the navigation Property... But if you want to keep it that way and only carry Personal Physique you can use ctx.Empresa.People.Oftype<Personal>. Load()

  • @Tiago I’ll already see yes, just a moment I’m having to model some migration tables here at the service and I see... :)

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.