Entity framework 实体框架赢得';t在具有两级关系的新实体上保存更改

Entity framework 实体框架赢得';t在具有两级关系的新实体上保存更改,entity-framework,savechanges,Entity Framework,Savechanges,我正在使用ADO.NET实体框架构建一个ASP.NET MVC站点。 我有一个实体模型,其中包括通过外键关联的这些实体: 报告(ID、日期、标题、报告类型、ID等) 子报表(ID、报表文本等)-与报表的一对一关系。 ReportSource(ID、名称、描述)-与Sub_报告的一对多关系。 ReportSourceType(ID、名称、描述)-与ReportSource的一对多关系 联系人(ID、姓名、地址等)-与报告来源的一对一关系 每种类型的子报表都有一个Create.aspx页

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

报告(ID、日期、标题、报告类型、ID等)

  • 子报表(ID、报表文本等)-与报表的一对一关系。
    • ReportSource(ID、名称、描述)-与Sub_报告的一对多关系。
      • ReportSourceType(ID、名称、描述)-与ReportSource的一对多关系
      • 联系人(ID、姓名、地址等)-与报告来源的一对一关系
每种类型的子报表都有一个Create.aspx页面。post event方法返回一个新的Sub_报告实体

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

  • 从页面的字段中设置新报表实体的属性
  • 从页面的字段中设置子报表实体的特定属性
  • 将子报表实体的报表设置为在1中创建的新报表实体
  • 给定页面提供的ID,查找ReportSource并将Sub_报告实体的ReportSource设置为找到的实体
  • 保存更改
  • 这个工作流程成功了好几个星期。上周有些事情发生了变化,不再起作用了。现在,我得到的不是保存操作,而是以下异常:

    UpdateException: "Entities in 'DIR2_5Entities.ReportSourceSet' participate in the 'FK_ReportSources_ReportSourceTypes' relationship. 0 related 'ReportSourceTypes' were found. 1 'Report_Source_Types' is expected." UpdateException:“DIR2_5Entities.ReportSourceSet”中的实体 参与“FK_ReportSources_ReportSourceTypes”关系。 找到0个相关的“ReportSourceTypes”。应为1个“Report\u Source\u Types” 调试可视化工具显示以下内容:

    • 子报表的ReportSource已设置并加载,其所有属性均正确
    • 报表源附加了有效的ReportSourceType实体
    在SQL探查器中,准备好的SQL语句看起来正常。有人能告诉我我遗漏了什么吗

    短暂性脑缺血发作

    注: 在这种情况下,报表和子报表始终是新实体。
    报表实体包含许多类型报表的公共属性,用于一般查询。子报表是特定的报表,其额外参数因类型而异。实际上,每种类型的子报表都有一个不同的实体集,但这个问题适用于所有子报表,因此我使用子报表作为一个简化示例。

    检查您的报表源是否加载了NoTracking选项,或者其EntityState==“Distached”。如果是这样,那就是您的问题所在,它必须在上下文中加载。

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

    我意识到我做这件事太晚了,但我也遇到了类似的问题,我花了大约3个小时才想出解决方案。我会发布代码,但它在家里——如果有人需要,我可以稍后再发布

    以下是一些需要检查的内容:

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

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

    由于创建了新的对象实例,我遇到了相同的错误“幕后”处于“添加”状态。这不明显。

    我出现此错误,因为表没有主键,它有FK引用,但没有PK


    添加PK并更新模型后,一切正常。

    我在将新实体添加到上下文中时出现了此错误,但忘记将新实体添加到对象图中其父集合中

    例如:

    Pet pet = new Pet();
    context.Pets.Add(pet);
    // forgot this: petOwner.Pets.Add(pet);
    

    您可能想给出一个代码片段,它肯定会帮助我了解发生了什么。通常,这样的问题在一些代码中更容易看到。感谢您的回复,Alex。我稍后会尝试发布一些代码。现在我只是将其标记为EF为1.0,并用存储过程替换了我的代码。谢谢您的评论。我将已经在调试模式下检查了EntityState,但没有检查NoTracking选项。我确实在您的评论提示下尝试了它,但没有任何乐趣。我还重新生成了我的模型,以查看上次更新是否导致了问题,但没有任何影响。为了克服此问题,我只编写了一个存储过程来清理所有相关对象并删除实体可以使用Visual Studio数据提示找到添加和更改列表(在与下面类似的行上设置断点,并将其悬停在ObjectContext部分上)。this.ObjectContext.SaveChanges()。在数据提示中,通过…base{System.Data.Objects.ObjectContext}向下钻取到“_AddIdentityStore”->ObjectStateManager->Non Public members->\u AddedEntityStore这是我在调试中运行时所做的。在我的例子中,对运行时属性的检查表明所有数据都已就绪,所有键都已填充且正确。我想EF只是没有跟踪到预期的级别。发布时我很匆忙,所以我刚刚决定使用存储过程来保存复杂的实体树。您好,我想我遇到了您要解决的问题