EF Code First – WithMany()

我最近来过类ManyNavigationPropertyConfiguration ,在那个类中,我发现了一个名为WithMany()的方法,有2个重载。

第一个重载: WithMany()

将关系配置为很多:在关系的另一侧没有导航属性。

第二个重载: WithMany(Expression<Func<TTarget, ICollection>>)

将关系配置为很多:很多在关系的另一端具有导航属性。

现在是我的问题,为什么你要将关系配置为很多:许多没有导航属性(第一次重载)? 我没有看到任何有用的场景……有什么想法吗?

一个例子可能是这个模型:

 public class User { public int UserId { get; set; } public string Name { get; set; } public ICollection Roles { get; set; } } public class Role { public int RoleId { get; set; } public string Description { get; set; } } 

如果您从不想检索具有特定角色的所有用户 ,请添加导航属性…

 public ICollection Users { get; set; } 

…对Role类来说是不必要的开销。

但是你仍然必须EF告诉UserRole之间的多对多关系存在……

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

…因为默认约定映射会创建一个错误的关系,即一对多关系,对应于此映射:

 modelBuilder.Entity() .HasMany(u => u.Roles) .WithOptional(); 

请注意,导航属性的选择位于目标的另一侧

让我们看一个例子,即使这个具体情况可能不是我的观点的完美插图……如果你想跟踪数学测试,并重复使用问题,你可能有两个表( TestsQuestions )有多对多的关系; 每个测试都有几个问题,每个问题都可以出现在几个测试中。 但是,您可能不需要获得特定问题所针对的测试集合 – 即使您知道问题可以出现在多个测试中,您也不会对其感兴趣。
因此,在声明这个时使用.WithMany()重载,因此您获得了一个导航属性来获取测试的问题( theTest.Questions() )但没有另一种导航属性( theQuestion.Tests() )。 但是你仍然需要一个多对多的关系,因为测试和问题都可以有许多其他的。
我同意在这种特定的情况下,这种设置可能没有意义,但肯定会有这样的情况,在这种情况下, .WithMany()重载让你无需定义属性(以及每一个属性的lambda表达式) )你永远不需要。