Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF 4.1 Mapping Problem

I have a class that have a relationship with itself:

public class Person
{
    public long ID { get; set; }
    public string Name { get; set; }

    public virtual Person Mother { get; set; }
    public virtual Person Father { get; set; } 
}

When EF 4.1 is trying to map this class I'm getting the follow error: 'Unable to determine the principal end of an association between the types 'Model.Person' and 'Model.person'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.'

I already tried the solution of the topic EF 4.1 - Model Relationships without success.

How I can fix that?

Thanks!

like image 387
UbirajaraMNJ Avatar asked May 22 '11 17:05

UbirajaraMNJ


1 Answers

Because it's naturally a one-to-many relationship (a person must have one father and one mother but can have many sons and daughters) I'd model it like this:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .HasRequired(p => p.Father)
        .WithMany();

    modelBuilder.Entity<Person>()
        .HasRequired(p => p.Mother)
        .WithMany();
}

This will create two required foreign keys in the database table with name Mother_ID and Father_ID by convention.

Edit

If you want to be able to create persons without Mother and Father you can make the relation optional instead of required:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .HasOptional(p => p.Father)
        .WithMany();

    modelBuilder.Entity<Person>()
        .HasOptional(p => p.Mother)
        .WithMany();
}

Then the foreign keys in the database table are nullable.

If you don't like the default column names for your foreign keys (Mother_ID and Father_ID) you can customize the column names in your mapping:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .HasOptional(p => p.Father)
        .WithMany()
        .Map(m => m.MapKey("FatherID"));

    modelBuilder.Entity<Person>()
        .HasOptional(p => p.Mother)
        .WithMany()
        .Map(m => m.MapKey("MotherID"));
}
like image 180
Slauma Avatar answered Oct 21 '22 09:10

Slauma