实体框架多对多问题

Sis*_*utl 8 many-to-many entity-framework

请帮助EF n00b设计他的数据库.我有几家公司生产多种产品,因此公司和产品之间存在多对多的关系.我有一个与他们相关的中间表,Company_Product.

每个公司/产品组合都有一个独特的SKU.例如,Acme小部件具有SKU 123,但Omega小部件具有SKU 456.我将SKU添加为Company_Product中间表中的字段.

EF生成了一个模型,该模型在公司和Company_Product表之间具有1:*关系,并且产品和Company_Product表之间具有1:*关系.我真的想要:公司和产品之间的关系.但是,最重要的是,无法直接从模型访问SKU.

我是否需要将SKU放在自己的表中并编写连接,还是有更好的方法?

Sam*_*ham 33

我刚刚在一个新的VS2010项目(EFv4)中对此进行了测试以确定,这就是我发现的内容:

如果中间的关联表(Company_Product)只有2个外键到其他表(CompanyID和ProductID),那么将所有3个表添加到设计器最终会建模多对多关系.它甚至没有为Company_Product表生成一个类.每个公司都有一个产品系列,每个产品都有一个公司系列.

但是,如果您的关联表(Company_Product)具有其他字段(例如SKU,它自己的主键或其他描述性字段,如日期,描述等),那么EF建模器将创建一个单独的类,它会执行您所做的事情.已经看过了.

让中间阶段与公司和产品之间存在1:*关系并不是一件坏事,您仍然可以通过一些简单的查询获得所需的数据.

// Get all products for Company with ID = 1
var q =
    from compProd in context.Company_Product
    where compProd.CompanyID == 1
    select compProd.Product;
Run Code Online (Sandbox Code Playgroud)

确实,例如,当您已经加载了实体对象时,导航模型的关系并不容易,但这就是数据层的用途.封装获取所需数据的查询.如果你真的想要摆脱那个中间的Company_Product类,并且在类模型中直接表示多对多,那么你将不得不去除Company_Product表只包含2个外键,并摆脱它SKU.

实际上,我不应该说你必须这样做......你可以在设计师中做一些编辑,无论如何都要这样设置.我会试一试并报告.

UPDATE

将SKU保留在Company_Product表中(意味着我的EF模型有3个类,而不是2个;它创建了Company_Payload类,其他2个表格为1:*),我尝试在公司和产品之间直接添加关联.我遵循的步骤是:

  • 右键单击设计器中的Company类
  • 添加>关联
  • 将左侧的"结束"设置为公司(应该已经是)
  • 在产品右侧设置"结束"
  • 将两个多重性更改为"*(多个)"
  • 导航属性应命名为"产品"和"公司"
  • 点击OK.
  • 右键单击模型中的关联>单击"表映射"
  • 在"添加表格或视图"下,选择"Company_Product"
  • 地图公司 - > ID(左侧)到CompanyID(右侧)
  • 将产品 - > ID(左侧)映射到ProductID(右侧)

但是,它不起作用.它给出了以下错误:错误3025:从第175行开始映射片段时出现问题:必须指定表Company_Product的所有关键属性(Company_Product.SKU)的映射.

因此,特定关联无效,因为它使用Company_Product作为表,但不会将SKU字段映射到任何内容.

此外,在我研究这个时,我从"Entity Framework 4.0 Recipies"一书中看到了这个"最佳实践"小窍门(请注意,对于具有额外字段的关联表,除了2个FK之外,它们还将额外字段称为"有效负载" ".在您的情况下,SKU是Company_Product中的有效载荷).

最佳实践

不幸的是,一个以几个无负载,多对多关系开始的项目通常最终会产生多个有效负载,多对多关系.重构模型,特别是在开发周期的后期,以适应多对多关系中的有效载荷可能是乏味的.不仅引入了其他实体,而且通过关系的查询和导航模式也发生了变化.一些开发人员认为,每个多对多关系应该从一些有效载荷开始,通常是一个合成密钥,因此不可避免地增加更多有效载荷对项目的影响要小得多.

所以这是最好的做法.如果您具有无负载,多对多关系,并且您认为有可能随着时间的推移而改变以包含有效负载,请从链接表中的额外标识列开始.将表导入模型时,您将获得两个一对多关系,这意味着您编写的代码和您拥有的模型将为项目成熟时出现的任意数量的其他有效负载列做好准备.额外的整数标识列的成本通常是一个非常小的代价,以保持模型更灵活.

(来自第2章.实体数据建模基础知识,2.4.使用有效负载建模多对多关系)

听起来不错.特别是因为你已经有了一个有效载荷(SKU).