实体框架 6 - 缺失的表只有主键参考不同表

14

我们正在学习Entity Framework 6.1(从NuGet获取)并逐步放弃Linq2Sql。我们有少量表格将两个独立的表格关联起来,如下所示。

EF6基于数据库的生成

数据库图:

输入图像说明

模式概述:

输入图像说明

在Visual Studio中进行空类库操作,在进行基于数据库的EF6 EDMX文件时,该图仅生成TableA和TableC——TableB不会被生成。

输入图像说明

Visual Studio视图:

输入图像说明

您可以看到仅创建了TableA和TableC。但技术上应该创建TableB,因为您希望能够管理这些引用。

在图表中A和C之间的关联:

输入图像说明

我觉得我缺少一个选项,或者误解了Entity Framework的一个关键概念。有什么办法可以使用T4生成漏掉的TableB?EDMX文件确实显示了它,但由于某些原因它没有被生成到一个带有两个属性指示关系的.CS文件中。

我们需要这样做的主要原因是,我们扩展了EF6 T4模板,添加了一些工厂模式以匹配我们现有的模型。因为它不为TableB生成类,所以我们无法获得我们正在寻找的自动生成的代码。

您有什么想法/建议吗?谢谢。


2
也许 EF 理解 TableB 没有自己的含义,只是用于多对多关系? - Disappointed
3个回答

7
EF不会生成弱实体或联接表,您需要通过流畅API或使用数据注释手动配置关系。根据微软网站上的关系约定:如果您在相同类型之间有多个关系(例如,假设您定义了Person和Book类,其中Person类包含ReviewedBooks和AuthoredBooks导航属性,Book类包含Author和Reviewer导航属性),则您需要使用数据注释或流利的API手动配置关系。有关更多信息,请参见数据注释 - 关系和流利的API - 关系。有关详细信息,请参见link。更新:在EDMX的情况下,以下解决方法可行(但需要维护)。
  1. 从数据库中删除连接表中的外键
  2. 从数据库更新EDMX
  3. 重新创建连接表中的外键

只要您不再从数据库更新您的模型,这个解决方法就可以使用。

建议的解决方案是将所有内容保留为EDMX生成的内容,并学习如何使用以下链接来进行此案例的crud操作,这些链接由用户“@TravisWhidden”报告为“有帮助”

  1. 插入/更新多对多实体框架。我该怎么做?
  2. https://www.youtube.com/watch?v=uMQwORSTGX4(视频)

如果我采用了代码优先的方法,这看起来会很有帮助 --- 但是因为我们正在使用“从数据库生成EF设计器”,所以我找不到在EDMX xml中设置数据流畅API或数据注释的位置。 - TravisWhidden
@TravisWhidden 你可以采用一个变通方法,先从联接表中删除主键,然后生成edmx文件后再把它们加回去。如果模型因为表没有主键而无法工作,那么就移除其中一个主键并尝试。 - Monah
主键的删除并没有起到作用,但是外键约束的删除却有帮助。但是,在把它们放回去后,当您按“从数据库更新”按钮时,XML中的关联将返回,并且当您尝试向表添加实体并在SaveChanges()之后抛出由于关联约束而引起的异常。如果他们需要'更新'EDMX文件,期望团队中的任何开发人员手动删除所有与这些表对应的关联不太合理。因此,虽然这是一种可能的解决方案,但仍在寻找更可维护的解决方案。 - TravisWhidden
好的,我现在明白了。那个链接中关于多对多关系的答案给了我一些线索。为了支持EF6模型,进行一些重构可能比试图将我们的旧设计强行适配更好。tableA.TableC.Add(tableC); 这样做对我们来说可以达到同样的效果,而无需管理任何CRUD工厂。在某种程度上,这可能更简单(尽管重构需要一些时间)。我想在这方面给你更多的赞扬,但是书面答案并不是真正的解决方案。评论提供了更好的指导方向。请修改答案,将其重定向到该链接作为对其他人的提示。 - TravisWhidden
@TravisWhidden 我会更新我的解决方案,包括链接。 - Monah
显示剩余3条评论

3

如@Hadi Hassan所述,EF不会“公开”或识别仅由其他实体组成的关系表。

解决方法:
如果您只需要“读取”数据

  1. 在模式中为TableB定义一个视图
  2. 然后从数据库中进行模型(.EDMX)更新(选择更新视图)
  3. 现在,您将能够使用EF上下文查询您的TableB数据。

如果您需要修改(创建、更新、销毁)TableB中的记录

  1. 在模式中创建相应的存储过程。

  2. 将您的存储过程导入到EF模型中作为函数。

  3. 现在,您可以从您的模型上下文调用这些函数进行其余CRUD操作。


0

我发现最简单的方法是在表中添加一个自增字段,并将此唯一字段作为主键。然后添加由两个外键组成的唯一约束。您可能需要删除表并重新创建它以便以这种方式设置,因为数据库不会喜欢删除现有的PK关系。

然后在实体模型中删除该表以及Entity可能已经创建的与此表中关系相关的任何导航属性。保存您的模型,重新构建,然后在图表中更新来自数据库。您的表现在应该像普通表一样出现在Entity中。


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