Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF Code First - WithMany()

I recently came by the class ManyNavigationPropertyConfiguration<TEntity, TTarget> , and within that class there I found a method named WithMany() with 2 overloads.

The first overload: WithMany()

Configures the relationship to be many:many without a navigation property on the other side of the relationship.

The second overload: WithMany(Expression<Func<TTarget, ICollection<TEntity>>>)

Configures the relationship to be many:many with a navigation property on the other side of the relationship.

Now is my question, why would you configure a relationship to be many:many without a navigation property (the first overload)? I dont see any scenarios where that would be helpful... Any thoughts?

like image 762
ebb Avatar asked May 08 '11 11:05

ebb


People also ask

How do you create a foreign key relationship in code first approach?

To create Foreign Key, you need to use ForeignKey attribute with specifying the name of the property as parameter. You also need to specify the name of the table which is going to participate in relationship. I mean to say, define the foreign key table. Thanks for reading this article, hope you enjoyed it.

How do I map a one to many relationship in Entity Framework?

“HasMany” and “WithMany” method is used to define one-to-many or many-to-many relation in entity framework. We can configure one-to-many relationships between People and PeopleAddress using Fluent API by the following code in the model class: protected override void OnModelCreating(DbModelBuildermodelBuilder)

How do I make Entity Framework Code First?

Step 1 − First, create the console application from File → New → Project… Step 2 − Select Windows from the left pane and Console Application from the template pane. Step 3 − Enter EFCodeFirstDemo as the name and select OK. Step 4 − Right-click on your project in the solution explorer and select Manage NuGet Packages…

How do I add a foreign key in Fluent API?

You can then configure foreign key properties by using the HasForeignKey method. This method takes a lambda expression that represents the property to be used as the foreign key.


2 Answers

An example might be this model:

public class User
{
    public int UserId { get; set; }
    public string Name { get; set; }
    public ICollection<Role> Roles { get; set; }
}

public class Role
{
    public int RoleId { get; set; }
    public string Description { get; set; }
}

If you are never interested to retrieve all users which are in a specific role, adding a navigation property ...

public ICollection<User> Users { get; set; }

... to the Role class would be unnecessary overhead.

But you still must EF tell that a many-to-many relationship between User and Role exists ...

modelBuilder.Entity<User>()
            .HasMany(u => u.Roles)
            .WithMany();

... because the default convention mappings would create a wrong relationship, namely a one-to-many relationship, corresponding to this mapping:

modelBuilder.Entity<User>()
            .HasMany(u => u.Roles)
            .WithOptional();
like image 80
Slauma Avatar answered Oct 13 '22 01:10

Slauma


Note that the choice for a navigation property is on the other side of the target.

Let's look at an example, even though this specific case might not be the perfect illustrator of my point... If you want to keep track of math tests, and re-use questions, you might have two tables (Tests and Questions) which have a many-to-many relationship; each test has several questions, and each question can appear on several tests. However, you might not ever need to get a collection of tests that a specific question is on - even though you know that questions can appear on more than one test, you aren't interested in which.
Thus, you use the .WithMany() overload when declaring this, so you get a navigational property to get the questions of a test (theTest.Questions()) but no navigational property the other way (theQuestion.Tests()). But you still need a many-to-many relationship, since both tests and questions can have many of the other.
I agree that in this specific case this setup might not make sense, but there is certainly cases where it does, and in those cases the .WithMany() overload lets you get by without defining properties (and a lambda expression for each one of them) you'll never need.

like image 43
Tomas Aschan Avatar answered Oct 12 '22 23:10

Tomas Aschan