Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Core: many-to-many relationship with same entity

Tags:

I am trying to map many-to-many relationship with the same entity. The User entity has an IList<User> data field for Contacts, which stores users' contacts/friends information:

public class User : DomainModel {     public virtual IList<User> Contacts { get; protected set; }     //irrelevant code omitted } 

When I try to use fluent API to map this many to many relationship, it gives me some trouble. Apparently, when I use HasMany() on the user.Contacts property, it has no WithMany() method to call next. The intellisense from Visual Studio only shows WithOne(), but not WithMany().

modelBuilder.Entity<User>().HasMany(u => u.Contacts).WithMany()  // gives compile time error: CS1061 'CollectionNavigationBuilder<User, User>' does not contain a definition for 'WithMany' and no extension method 'WithMany' accepting a first argument of type  

So why does this happen? Is there anything I did wrong to map this many-to-many relationship?

like image 926
Lord Yggdrasill Avatar asked Sep 29 '16 13:09

Lord Yggdrasill


People also ask

How does Entity Framework handle many-to-many relationships?

To configure many-to-many relationship Using Data Annotations, you need to create the Join Table in the model. The Join Table BookCategory will have properties for the primary key of both the table. It will have two navigational properties one each for Book and Category class.

How do you create a many-to-many relationship in EF core?

Many-to-many. Many-to-many relationships require a collection navigation property on both sides. They will be discovered by convention like other types of relationships. The way this relationship is implemented in the database is by a join table that contains foreign keys to both Post and Tag .

When would you use EF6 vs EF core?

Keep using EF6 if the data access code is stable and not likely to evolve or need new features. Port to EF Core if the data access code is evolving or if the app needs new features only available in EF Core. Porting to EF Core is also often done for performance.

What is OnModelCreating in Entity Framework?

The DbContext class has a method called OnModelCreating that takes an instance of ModelBuilder as a parameter. This method is called by the framework when your context is first created to build the model and its mappings in memory.


1 Answers

So why does this happen? Is there anything I did wrong to map this many-to-many relationship?

No, you didn't do anything wrong. It's just not supported. Current status here.

Many-to-many relationships without an entity class to represent the join table are not yet supported. However, you can represent a many-to-many relationship by including an entity class for the join table and mapping two separate one-to-many relationships.

With EF-Core you should create the entity for the mapping table. Such as UserContacts. A complete example in the docs, as mentioned in the comments. I haven't actually tested the code below, but it should look something like this:

public class UserContacts {     public int UserId { get; set; }      public virtual User User { get; set; }      public int ContactId { get; set; } // In lack of better name.     public virtual User Contact { get; set; } }  public class User : DomainModel {     public List<UserContacts> Contacts { get; set; } } 

And your modelBuilder.

  modelBuilder.Entity<UserContacts>()         .HasOne(pt => pt.Contact)         .WithMany(p => p.Contacts)         .HasForeignKey(pt => pt.ContactId);      modelBuilder.Entity<UserContacts>()         .HasOne(pt => pt.User)         .WithMany(t => t.Contacts)         .HasForeignKey(pt => pt.UserId); 
like image 179
smoksnes Avatar answered Sep 28 '22 04:09

smoksnes