【问题标题】:EF Code First - WithMany()EF 代码优先 - WithMany()
【发布时间】:2023-03-21 16:20:01
【问题描述】:

我最近来上课ManyNavigationPropertyConfiguration<TEntity, TTarget> ,在该类中,我发现了一个名为 WithMany() 的方法,其中包含 2 个重载。

第一个重载: WithMany()

将关系配置为 many:many 没有导航 另一边的财产 关系。

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

将关系配置为 many:many 带有导航属性 在关系的另一端。

现在我的问题是,为什么要将关系配置为 many:many 而没有导航属性(第一个重载)?我没有看到任何有用的情况...有什么想法吗?

【问题讨论】:

    标签: c# entity-framework ef-code-first


    【解决方案1】:

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

    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 类将是不必要的开销。

    但您仍然必须 EF 告知 UserRole 之间存在多对多关系...

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-26
        • 2012-05-17
        • 2018-02-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多