【问题标题】:EF Many to many relationship with additional propertiesEF 与附加属性的多对多关系
【发布时间】:2013-06-20 15:52:27
【问题描述】:

我知道这是一个重复的问题,我知道如果“中间”表中有其他属性,这是不可能的。

我知道如何获得 m:N 关系而不是 1:n-n-1 的效果,但我想听听其他想法。

如果我有三个实体 A、B 和 AB,其中 AB 使 A:B 关系成为可能,并且它具有其他属性。

使用 Databasefirst 方法,我想制作 A 和 B 的部分类。

public partial Class A
{
    public IEnumerable<EntityObject> Bs 
    {
        get
        {
            return this.Select(p=>p.AB.B);
        }
        set { //... }
    }
}

这样的事情是可能的。

只是在我的脑海中涂鸦。我现在正在度假,没有电脑,所以这个没有测试,只是写在我的手机上。

我发现这可能是在上下文处理或分离之后出现的问题,也包括在急切加载方法中。

有什么想法吗?

【问题讨论】:

  • 你为什么不分解你通过在每个实体中拥有ICollection 自动获得的多对多,并创建你自己的中间实体,它直接引用每个其他实体加上额外属性?在我意识到 EF 可以为你做这件事之前,我只是为 m-2-m 做这件事。
  • 我不确定你的意思。我目前拥有 A-AB-B 实体。你能详细解释一下你的意思吗
  • 您可以手动定义 AB 实体,它恰好有一个对 A 和 B 的引用(从而生成 m-2-m)。 A 将有一个 AB 的列表,B 将有一个 AB 的列表。然后你可以把你喜欢的东西放在 AB 上,因为你可以控制实体。这是从代码优先的角度来看的。
  • 不,你理解错了。我想在 A 中有一个 B 的集合,在 B 中有一个 A 的集合。我没有反对 AB,但我想用它作为代理,以便在 A 和 B 中有一个行为,就像那里一样不是 B 是 AB 表。我正在使用 AB 实体
  • 如果我误解了您的问题,请纠正我,但我能想到的最接近的类比是 Rails 中的 has_many B, :through =&gt; [AB] 语法。在 EF 的情况下,多对多关系不支持具有额外“有效负载”的连接表,因此您需要手动处理 AB,就像您正在做的那样。从那里开始,只需获取正确的 LINQ 查询以选择 AB 中的所有 B。你问的是这个吗?

标签: c# entity-framework partial-classes


【解决方案1】:

如果您已经将 AB 视为一个不同的实体,那么要从 A 中获取所有 B,您只需要这样:

public partial class A
{
    public IQueryable<B> Bs {
        get { return this.ABs.AsQueryable().Select(ab => ab.B).Distinct(); }
    }
}

与 EF 支持的内置多对多(没有任何有效负载)相比,我不确定它的性能如何,但它会满足您的要求。

【讨论】:

    【解决方案2】:

    如果技术上可行与否,将“中间表中的附加属性”表示为多对多关系是错误的,因为它隐藏了“中间表”具有商业意义,因此必须是一个独立的实体。

    RawMaterialProduct 是此类模型的一个经典示例:RawMaterial 可以在多个 Products 中使用,Product 可以由多个 RawMaterials 组成。介于两者之间的实体(可能称为RecipePart)包含Quantity,给定Product 中使用了多少给定RawMaterial

    如果您有例如产品ChocolateBar 并处理它与原材料的关系,您将处理一个配方,上面写着ChocolateBar 有60 个单位的Chocolate 和40 个单位的Milk,即@ 987654335@ 有一个RecipeParts 的集合,每个RecipePart 描述数量并引用相关的RawMaterialChocolateBar 没有在此业务模型中直接收集 RawMaterials。

    对于一个特定的查询(可能是一些统计数据),您可能只对其原材料感兴趣 - 巧克力棒是由巧克力和牛奶制成的,无论有多少单位 - 但这是您的商业模式和种类的特殊查询忽略某些完整详细模型信息的聚合。这就是你的助手属性this.Select(p=&gt;p.AB.B); 所做的:它不表达完整的关系,而是一个专门的查询,它说:只给我这个ProductRawMaterials,我不想知道每个数量。

    从特征上讲,您已将属性设置器 set { //... } 保留为存根。添加或更改实体时,很明显关系不能是多对多的。不能只将RawMaterials 的列表分配给Product。您必须添加每个RawMaterial 的单位数信息才能获得有效的Product 模型,这意味着Product 必须与“中间实体”RecipePart 相关。

    【讨论】:

    • 我完全同意你的看法。中间桌子的隐藏是无稽之谈。这是必需的。我想要实现的是不同的东西。我不想失去中间的桌子。我要它。我正在尝试一种简单的方法来从 A 中的实体操作 B 中的条目,因为中间实体是隐藏的。我再说一遍,我不想失去 AB 实体。我只是想模仿隐藏的方式。
    猜你喜欢
    • 2022-10-25
    • 2011-09-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    相关资源
    最近更新 更多