如何替换图形中间的实体?

时间:2016-11-29 16:40:50

标签: c# entity-framework

我有一个断开连接的实体框架图,它被发送到客户端并随更新一起返回。其中一个更新可能会替换图中间的实体。当我尝试替换它时,我收到 InvalidOperationException 并显示以下消息:

  

操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

为简单起见,模型看起来像这样:

Simple EF Model

导致异常的代码如下所示:

// Create a tree of objects
Root root = new Root() { Id = 1 };
Branch origBranch = new Branch() { Id = 3 };
Twig onlyTwig = new Twig() { Id = 5 };
Leaf onlyLeaf = new Leaf() { Id = 7 };

onlyTwig.Leaves.Add(onlyLeaf);
origBranch.Twigs.Add(onlyTwig);
root.Branches.Add(origBranch);

// Store the structure in the database using the container
using (Pot container1 = new Pot())
{
    container1.Roots.Add(root);
    container1.SaveChanges();
}

// Create a new Branch to replace the original 
Branch newBranch = new Branch() { Id = 11 };

// Add the Twig from the original object
newBranch.Twigs.Add(onlyTwig);

using (Pot container2 = new Pot())
{
    container2.Roots.Attach(root);

    // Replace the branch 
    root.Branches.Remove(origBranch);
    root.Branches.Add(newBranch);

    container2.SaveChanges(); // THROWS EXCEPTION !!
 }

我想通过删除旧实体,然后添加一个新的实体,我将满足“新关系必须定义...”标准,但它失败了。在我们的例子中,在数据库中使列可以为空可能会导致其他问题,第一个问题就是冒着数据库完整性的风险。那通常如何处理?

我解决了部分问题,主要是欺骗实体框架,使其相信它正在进行更新,而不是用新项目替换项目。解决方案的关键是设置相同的主键值,然后将实体状态设置为修改替换代码将在下面发布。

// Create a new Branch to replace the original 
// Make sure to use the id from the original saved object
Branch newBranch = new Branch() { Id = origBranch.Id };

// Add the Twig from the original object
newBranch.Twigs.Add(onlyTwig);

// Replace the original branch with the new branch
root.Branches.Remove(origBranch);
root.Branches.Add(newBranch);

using (Pot container2 = new Pot())
{
    // Attach the graph to the container.  The default state is unchanged.
    container2.Roots.Attach(root);

    // Trick entity framework into thinking the new branch with the 
    // same primary key is the original item with modifications
    container2.Entry(newBranch).State = EntityState.Modified;

    container2.SaveChanges();
}

但是,有时候用全新的实体替换实体,所以我仍然需要一个答案,如何 删除然后添加

0 个答案:

没有答案