替换父项并将子项链接到它后保存ObjectContext时出错

时间:2013-02-21 15:36:47

标签: entity-framework sqlite foreign-keys system.data.sqlite

在我的应用程序中,界面允许用户在Entity Framework模型中创建和删除实体。所有更改都会添加到ObjectContext,并仅在用户选择“保存”时保存。

我的问题最好通过以下简单示例询问:

我在两种实体类型之间有一个外键关系,我在这里称之为ParentChild。 SQLite中的数据库声明如下:

CREATE TABLE Parents   (ID INTEGER PRIMARY KEY);

CREATE TABLE Children  (ID INTEGER PRIMARY KEY,
                        ParentID INTEGER NOT NULL CONSTRAINT FK_ChildrenToParents REFERENCES [Parents](ID) ON DELETE CASCADE ON UPDATE CASCADE)

然后我在该数据库上构建一个Entity Framework模型,并对其执行以下操作(参见下面的代码):

  1. 创建Parent
  2. 保存
  3. 删除Parent
  4. 使用与原始
  5. 相同的ID号创建新的Parent
  6. 创建Child并为其提供新的Parent的ID号
  7. 保存(失败)
  8. demoDBEntities entities = new demoDBEntities();
    
    Parent originalParent = new Parent { ID = 1 };
    entities.Parents.AddObject(originalParent);
    
    entities.SaveChanges(); // First Save
    
    entities.Parents.DeleteObject(originalParent);
    
    Parent newParent = new Parent { ID = 1 };
    entities.Parents.AddObject(newParent);
    Child newChild = new Child { ID = 2, ParentID = 1 };
    entities.Children.AddObject(newChild);
    
    entities.SaveChanges(); // Second Save
    

    第二次调用SaveChanges()时出现以下错误:

    "Unable to insert or update an entity because the principal end of the 'demoDBModel.FK_Children_0_0' relationship is deleted."

    似乎问题是实体框架将新的Child项链接到originalParent项,然后将其删除并替换为newParent项。这可能听起来很自负,但在我的应用程序中很自然地发生。

    我有什么方法可以解决这个问题吗?

    PS:我知道重复使用数据库条目的ID号是不好的做法 - 但是,在我的情况下,ID号是资产号,理论上可以重复使用。也就是说,如果客户端创建错误的Parent,然后删除它,重新创建它,然后创建Child项,则通常会发生上述情况。

1 个答案:

答案 0 :(得分:2)

您可以尝试设置其中一个导航属性(您必须至少有一个),而只使用一次ParentID调用来添加完整的对象图,而不是设置外键属性AddObject。上下文:

或者:

//...
entities.Parents.DeleteObject(originalParent);

Child newChild = new Child { ID = 2 };
Parent newParent = new Parent { ID = 1, Children = new List<Child>{ newChild } };
entities.Parents.AddObject(newParent);

entities.SaveChanges();

或者:

//...
entities.Parents.DeleteObject(originalParent);

Parent newParent = new Parent { ID = 1 };
Child newChild = new Child { ID = 2, Parent = newParent };
entities.Children.AddObject(newChild);

entities.SaveChanges();