实体框架不会将SaveChanges保存在具有两级关系的新实体上

entity-framework savechanges

我正在使用ADO.NET实体框架构建ASP.NET MVC站点。我有一个包含这些实体的实体模型,由外键关联:

报告(ID,日期,标题,Report_Type_ID等)

  • SubReport(ID,ReportText等) - 与Report的一对一关系。
    • ReportSource(ID,Name,Description) - 与Sub_Report的一对多关系。
      • ReportSourceType(ID,Name,Description) - 与ReportSource的一对多关系。
      • 联系人(ID,姓名,地址等) - 与Report_Source的一对一关系。

每种类型的SubReport都有一个Create.aspx页面。 post事件方法返回一个新的Sub_Report实体。

以前,在我的post方法中,我遵循了这个过程:

  1. 从页面的字段中设置新报表实体的属性。
  2. 从页面的字段中设置SubReport实体的特定属性。
  3. 将SubReport实体的报告设置为在1中创建的新报告实体。
  4. 给定页面提供的ID,查找ReportSource并将Sub_Report实体的ReportSource设置为找到的实体。
  5. 保存更改。

这个工作流程成功完成了几周。然后上周发生了一些变化,它不再起作用了。现在取代了保存操作,我得到了这个例外:

UpdateException: "Entities in 'DIR2_5Entities.ReportSourceSet' 
participate in the 'FK_ReportSources_ReportSourceTypes' relationship. 
0 related 'ReportSourceTypes' were found. 1 'Report_Source_Types' is expected."

调试可视化工具显示以下内容:

  • SubReport的ReportSource已设置并加载,其所有属性都是正确的。
  • Report_Source附加了一个有效的ReportSourceType实体。

在SQL事件探查器中,准备好的SQL语句看起来不错。任何人都可以指出我错过了哪些显而易见的事情?

TIA

注意:在这种情况下,Report和SubReport始终是新实体。报表实体包含许多类型报表共有的属性,用于通用查询。子报告是具有不同类型的额外参数的特定报告。实际上每种类型的SubReport都有不同的实体集,但这个问题适用于所有这些,所以我使用SubReport作为简化示例。

一般承认的答案

如果您的数据库表彼此之间具有1 - 1的关系,则会发生这种情况。在您的示例中,reportsourceset需要一个带有它引用的id的reportsorttypes。当我的关系将两个主键从相对的表链接在一起时,我遇到了这个问题。


热门答案

我意识到我已经迟到了,但我遇到了类似的问题,在我提出解决方案之前,我已经整理了大约3个小时。我会发布代码,但它在家里 - 如果有人需要,我可以稍后再做。

以下是一些要检查的事项:

  • 在SaveChanges()调用上设置断点并深入检查对象上下文。您应该看到上下文的添加和更改列表。当我第一次看时,我发现它试图添加我所有相关的对象而不是仅指向它们。在您的情况下,上下文可能正在尝试添加新的Report_Source_Type。
  • 与前一点相关,但如果您要检索报告源,请确保通过其实体键从数据库中检索它并正确附加到上下文。如果没有,您的上下文可能会认为它是一个新项目,因此不会设置其所需的关系。

从内存中,我使用context.GetObjectByKey方法检索我的引用,然后使用context.Attach方法将这些对象显式附加到上下文,然后将它们分配给原始对象的属性。



许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因