Entity framework 如何在Entity framework 4中进行深度复制(克隆)?

Entity framework 如何在Entity framework 4中进行深度复制(克隆)?,entity-framework,entity-framework-4,deep-copy,Entity Framework,Entity Framework 4,Deep Copy,如何在Entity framework 4中进行深度复制(克隆)? 我需要获取EntityObject的副本以及所有相关对象的副本。这是我进行常规深度复制的方式: public static T DeepClone<T>(this T obj) { using (var ms = new MemoryStream()) { var bf = new BinaryFormatter(); bf.Serial

如何在Entity framework 4中进行深度复制(克隆)?
我需要获取EntityObject的副本以及所有相关对象的副本。

这是我进行常规深度复制的方式:

    public static T DeepClone<T>(this T obj)
    {
        using (var ms = new MemoryStream()) {
            var bf = new BinaryFormatter();
            bf.Serialize(ms, obj);
            ms.Position = 0;
            return (T)bf.Deserialize(ms);
        }
    }
public static T DeepClone(此T对象)
{
使用(var ms=new MemoryStream()){
var bf=新的二进制格式化程序();
bf.序列化(ms,obj);
ms.Position=0;
返回(T)bf.反序列化(ms);
}
}

我肯定以前有人问过这个问题。无论哪种方式,你都需要小心。克隆过程可能会使用反射,从而在查询属性进行反射时调用EF支持的延迟数据加载


如果您正在执行此操作,请确保无论您使用什么方法将实例克隆为实际的POCO类(我假设您使用的是POCO),这应该可以解决延迟加载问题。这只是一个想法。

我怀疑您不一定需要深度克隆—一个具有复制属性的新对象通常就足够了—这样,如果重新分配属性,它将不会与您克隆的原始EntityObject发生冲突

顺便说一句,我认为延迟加载没有问题——这正是您想要的

发件人:


如果禁用延迟加载,延迟数据加载仍然是一个问题吗。只要你能处理空值。应该没问题。如果您的实体具有循环引用,那么您可能会得到StackOverflowException。
public static T CopyEntity<T>(MyContext ctx, T entity, bool copyKeys = false) where T : EntityObject
{
    T clone = ctx.CreateObject<T>();
    PropertyInfo[] pis = entity.GetType().GetProperties();

    foreach (PropertyInfo pi in pis)
    {
        EdmScalarPropertyAttribute[] attrs = (EdmScalarPropertyAttribute[])pi.GetCustomAttributes(typeof(EdmScalarPropertyAttribute), false);

        foreach (EdmScalarPropertyAttribute attr in attrs)
        {
            if (!copyKeys && attr.EntityKeyProperty)
                continue;

            pi.SetValue(clone, pi.GetValue(entity, null), null);
        }
    }

    return clone;
}
Customer newCustomer = CopyEntity(myObjectContext, myCustomer, false);

foreach(Order order in myCustomer.Orders)
{
    Order newOrder = CopyEntity(myObjectContext, order, true);
    newCustomer.Orders.Add(newOrder);
}