how to do many to many with the same table with EF4 Code First
Asked Answered
B

1

9

I have this schema:

create table Person
(
id int identity primary key,
name nvarchar(30)
)

create table PersonPersons
(
PersonId references Person(id),
ChildPersonId references Person(id)
)

how to create the classes to map them using EF4 Code First CTP5 ?

Boden answered 24/2, 2011 at 9:50 Comment(1)
possible duplicate of Entity Framework 4 CTP 5 Self Referencing Many-to-ManyTristantristas
P
10

For the POCO...

class Person
{
    public Guid PersonId { get; set; }
    public virtual Person Parent { get; set; }
    public virtual ICollection<Person> Children { get; set; }
}

...set up the mapping in the DbContext...

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .HasOptional(entity => entity.Parent)
            .WithMany(parent => parent.Children)
            .HasForeignKey(parent => parent.PersonId);
}

...will give you a default implementation. If you need to rename the table explicitly (and want a many-to-many relationship), add in something like this...

class Person
{
    public Guid PersonId { get; set; }
    public virtual ICollection<Person> Parent { get; set; }
    public virtual ICollection<Person> Children { get; set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    ConfigureProducts(modelBuilder);
    ConfigureMembership(modelBuilder);

    modelBuilder.Entity<Person>()
        .HasMany(entity => entity.Children)
        .WithMany(child => child.Parent)
        .Map(map =>
        {
            map.ToTable("PersonPersons");
            map.MapLeftKey(left => left.PersonId, "PersonId"); 
            map.MapRightKey(right => right.PersonId, "ChildPersonId");
            // For EF5, comment the two above lines and uncomment the two below lines.
            // map.MapLeftKey("PersonId");
            // map.MapRightKey("ChildPersonId");
        }); 
}
Pathos answered 26/2, 2011 at 17:38 Comment(4)
where do I connect the .Map( map => with everything else ?Boden
edited above to show MTM configuration with .Map(). I imagine there might be a way to define both a Person and a PersonPersons POCO directly too.Pathos
Note: in EF 5.0, just change map.MapLeftKey(left => left.PersonId, "PersonId"); to map.MapLeftKey("PersonId");, and do so for the right key.Impeccable
I used this design and then I found out that the table will prevent you from deleting entities. Brilliant.Slipperwort

© 2022 - 2024 — McMap. All rights reserved.