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

问题描述 投票:3回答:1

在我的应用程序中,该界面允许用户在实体框架模型中创建和删除实体。所有更改都添加到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
)

然后,我在该数据库上构建一个实体框架模型,并对它执行以下操作(请参见下面的代码):

  1. 创建Parent
  2. 保存
  3. 删除Parent
  4. 使用与原始ID相同的ID号创建一个新的Parent
  5. 创建Child并为其提供新的Parent的ID号
  6. 保存(失败)
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项目,则通常会发生上述情况。

entity-framework sqlite foreign-keys system.data.sqlite
1个回答
3
投票

[而不是设置外键属性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();
© www.soinside.com 2019 - 2024. All rights reserved.