检索后标记为已更改的EF6.0条目

时间:2018-06-05 18:51:35

标签: entity-framework-6

C#7.2,.NET 4.7.1

我们得到的例外实际上是“关系无法更改,因为一个或多个外键属性是不可为空的”并且我查看了该异常的响应,但我不认为它们'相关,因为我可以在不进行任何添加/删除/更新的情况下得到此错误。

A类有许多B类,它有很多C类。

在对A执行更新之前,该方法执行此操作:

var value = db.A.Where(x => x.Identifier == updated.Identifier)
                .Include(x => x.A.Select(b => b.C)).ToList();

如果我执行db.ChangeTracker.DetectChanges()并查看其条目列表,则除了其中一个预期的C对象之外,其他所有对象都已被修改。然而,比较原始值和当前值没有显示出差异。

要明确:在上述转让之前,上下文未经修改; DetectChanges并查看列表中有0个条目。如果I DetectChanges再次出现在上述行之后,该列表会有5个条目。

现在是棘手的部分,我确定问题源于何处。该方法在正常情况下工作正常,但我们正在尝试引入一个新的函数,其中A类被复制到一个新实例中。要做到这一点,我们:

  1. 在一个上下文中检索要复制的对象,在检索后关闭上下文。
  2. A.DbId = -1; A.B.ForEach(b => {b.DbId = -1; b.C.ForEach(c => c.DbId = -1);
  3. 然后使用新的上下文,调用与正常添加新A时相同的方法。
  4. 我认为很明显副本中出现了问题,但是查看数据库,所有参考文献似乎都是正确的;我们只是难以理解为什么我们会以这种方式看待问题。如何拉动数据导致变化?并且要明确:当我们尝试在复制后复制数据时,会发生此异常;我们在复制过程中没有发现任何问题。

    配置: 一个HasMany(x => x.B)

    B与其他两个定义

    无关

    C HasRequired(x => x.B).WithMany(x => x.C).Map(x => x.MapKey(“BDbId”);

    感谢阅读,如果需要任何其他信息,请告诉我。

    更新: 好吧,我们停止了例外,但我们不知道为什么。上面步骤3中提到的方法在其中有一行,它将为每个B添加一个新的C.我们不希望这个行为用于新函数,因此添加了一个额外的检查以防止使用新函数和异常no更长的时间。

    提供更多背景信息: 程序启动并作为其中的一部分,调用仅在非常特定的情况下执行此数据副本的函数。完成后,程序继续初始化。之后,用户可以执行导致特定对象A的WCF请求的操作。客户端修改A,然后进行WCF调用以保存这些更改。正是这次更新的调用抛出异常

    编辑2:花了一些时间研究这个。数据库中的条目看起来很好,参考C回到B是正确的。我可以在不调用复制代码的情况下运行程序,因此在除了创建上下文和加载A之外什么都不做的程序的新实例中,它仍然存在这个问题。

    这次我注意到了导致异常的原因:加载的A实例有B只有一个C,而在数据库中实际上有3个C引用了B.所以当我告诉Entity时检索A,它到达那些B并决定它不想要所有的Cs。有一次它只检索到1 C,从那以后我一直看到2;我不知道改变了什么。但是当你去保存A时,它显然是试图将丢失的C的FK设置为​​null,这是不允许的,我得到了例外。

    我可以使用FK对B和C表进行选择/加入就好了,所以我不知道实体在数据库中看到的是什么,我不是。

    附加信息:当在上面的步骤3中复制数据时,我将它传递给2。这些As共享6个B中的5个(每个具有不同的第六个B)。添加这些As的代码首先在处理第一个A时向B添加一个新的C,然后在处理第二个A时向同一个B添加第二个新的C.似乎只是这些B导致了麻烦,但我只是无法理解为什么这样的事情不起作用。

    这是继承的代码/ db。我们已经有了模型,我们已经有了数据库,所以我认为我们不是代码或数据库;它们只是存在,然后我们有一些映射某些东西的配置。另一个具有1对N关系的类仅在数据库中定义FK。但是C不仅在数据库中定义FK,而且在配置中定义FK。我试着评论出配置定义,但它没有什么区别;仅供参考。

0 个答案:

没有答案