实体框架重复对象和所有子属性 [英] Entity Framework duplicate object and all child properties

查看:62
本文介绍了实体框架重复对象和所有子属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

示例结构

public class Page
{
    public int PageId { get; set; }
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public virtual List<Section> Sections { get; set; }
}

public class Section
{
    public int SectionId { get; set; }
    public int PageId { get; set; }
    public virtual Page Page { get; set; }
    public virtual List<Heading> Headings { get; set; }
}

public class Heading
{
    public int HeadingId { get; set; }
    public int SectionId { get; set; }
    public virtual Section Section { get; set; }
}

值得注意的是,我的实际结构比这更多,但这应该足以解释我要实现的目标。

It's worth noting that my actual structure has more levels than this but this should be enough to explain what I'm trying to achieve.

因此,我加载了 Page 对象,然后克隆了该对象对象,并对 Page 的属性进行一些小的更改,即 Prop1 Prop2

So I load my Page object I then Clone that object and make some minor changes to the properties of Page i.e. Prop1, Prop2

Page pageFromDb = getPageMethod();
Page clonedPage = pageFromDb.Clone();
clonedPage.Prop1 = clonedPage.Prop1 + " Cloned";
addPageMethod(clonedPage); //Adds the page to db

在上面的示例 clonedPage 结构很好,新的 Page 已添加到数据库。但是我相信,因为已设置了子对象的ID,并且子对象的关系始终是一对多。原始对象 pageFromDb 将失去所有作为实体框架的子代,而不是为克隆的<$ c创建新的 Section 对象$ c>页面会将 Section.PageId 更新为新插入的页面。

In the example above clonedPage structure is fine and a new Page is added to the database. However I believe because the Id's of the child objects are set and the relationship of the children is always one to many. The original object pageFromDb will lose all it children as entity framework instead of creating new Section objects for the cloned Page will update the Section.PageId to the newly inserted page.

我相信对此的解决方法是将 foreach foreach 等,然后将所有ID设置为 0 在插入之前,实体框架将为每个对象创建新记录。有什么更简单/更好的方法可以在实体框架环境中克隆对象??

I believe a fix for this would be to foreach, foreach, etc. and set all the Id's to 0 before inserting then entity framework will create new records foreach object. Is there any easier/better way to clone an object in an entity framework environment.?

推荐答案

以便实体框架能够处理如果将克隆作为一个完整的新对象图保留下来,则该图中的所有实体都必须与检索根实体的上下文断开连接

In order for Entity Framework to treat the clone as an entire new object graph when persisting the graph, all entities in the graph need to be disconnected from the context in which the root entity was retrieved.

这可以在上下文中使用 AsNoTracking 方法来完成。

This can be done using the AsNoTracking method on the context.

例如,这将从数据库中提取页面和相关部分的图形并关闭跟踪。实际上,这是一个克隆,就像您将其添加到Page DbSet并将其保存将在数据库中创建一个全新的对象图一样。即新的Page实体和新的Section实体。请注意,您无需调用 Clone 方法。

For example, this will pull a page and associated sections graph from the database and turn off tracking. Effectively this is a clone as if you add this to your Page DbSet and save it will create an entirely new object graph in the database. I.e. a new Page entity and new Section entities accordingly. Note, you wont need to call your Clone method.

var clone = context.Pages
    .AsNoTracking()
    .Including(pages => pages.Sections)
    .Single(...);
context.Pages.Add(clone);
context.SaveChanges(); // creates an entirely new object graph in the database

这篇关于实体框架重复对象和所有子属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆