EF Code First - WithMany()

18
我最近遇到了ManyNavigationPropertyConfiguration<TEntity, TTarget>这个类,类中有一个名为WithMany()的方法,有两个重载。
第一个重载:WithMany() 配置关系为多对多,另一个方向没有导航属性。
第二个重载:WithMany(Expression<Func<TTarget, ICollection<TEntity>>>) 配置关系为多对多,并指定另一个方向的导航属性。
现在我的问题是,为什么要配置关系为多对多且另一个方向没有导航属性(第一个重载)?我没看出来在哪些情况下会有帮助... 你有什么想法吗?
2个回答

41

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

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; }
}

如果你从不想检索具有特定角色的所有用户,可以添加一个导航属性……

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

将访问Role类的导航属性添加到User类中会增加不必要的开销。

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

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

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

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

7
请注意,导航属性的选择位于目标的另一侧。
让我们看一个例子,即使这个特定的情况可能不是我观点的完美说明……如果你想跟踪数学测试,并重复使用问题,你可能有两个表(Tests和Questions)之间存在多对多关系;每个测试都有几个问题,每个问题可以出现在几个测试中。然而,你可能永远不需要获取某个问题所在的测试集合 - 即使你知道问题可以出现在多个测试中,你也不感兴趣。
因此,在声明此项时,您使用`.WithMany()`重载,以便获得一个导航属性来获取测试的问题(`theTest.Questions()`),但没有反向导航属性(`theQuestion.Tests()`)。但你仍然需要一个多对多的关系,因为测试和问题都可以有很多其他的东西。
我同意,在这种特定情况下,这种设置可能没有意义,但在某些情况下,它确实有意义,而在这些情况下,`.WithMany()`重载让您无需定义您永远不需要的属性(和每个属性的lambda表达式)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接