使用EF6的深度克隆实体

时间:2015-06-17 14:25:59

标签: .net entity-framework entity-framework-6

我一直在研究这个问题,我仍然没有找到克隆实体的解决方案,并且能够保存它,包括所有级别的子关系。

有没有人知道如何做到这一点?

BTW我使用AsNoTracking()然后使用Include(“Child ...”),但我在我的数据库中有5个级别的关系,需要包含大约100个表,所以我在自动这样做的方式

1 个答案:

答案 0 :(得分:0)

我尝试了3种不同的方式,使用序列化(在大多数情况下由于Lazy加载而无法使用),在具有反射的基础实体上实现ICloneable并使用自定义属性来控制克隆行为(我认为您正在寻找为此)并在每个实体上实现ICloneable。

实际上我在每个实体上都实现了ICloneable。通常我这样做:
1. MemberwiseClone()
2.调用相关实体的ICloneable.Clone来填充属性(仅限于某些属性
3.在其他一些相关实体上,我做了一个浅层复制(取决于需要)

我知道这很糟糕,但根据我的经验,如果我在项目启动时使用其他方法Clone工作正常,但在6个月后,在某些实体上调用Clone克隆了数据库的一半。

在您的情况下,激活延迟加载后,您可以使用反射 1.忽略简单的财产
2.为每个复杂的财产打电话克隆 3.在每个调用Clone的ICollection属性上执行foreach并将结果添加到相应的列表

此方法的问题是您每次都会克隆整个数据库。您可以决定停止某些实体覆盖克隆或在属性上使用自定义属性,但您需要一些东西来避免克隆整个数据库。

如果你没有激活延迟​​加载,你可以在克隆之前调用这些方法。

context.Entry(myEntry).Reference("myRefProp").Load(); 
context.Entry(myEntry).Collection("myColl").Load(); 

但他们没有解决你的问题。

修改
我仍然有代码来应用这种方法(带有属性),我从来没有使用它,但如果你需要我可以在某处发布它。 实际上我总是在每个实体上实现ICloneable,因为在克隆实现中使用属性来停止序列化或停止它最好在克隆实现中停止它。