克隆LINQ To SQL对象Extension方法抛出对象dispose异常

时间:2010-06-15 21:22:40

标签: linq-to-sql serialization c#-3.0 clone datacontract

我有这个扩展方法来克隆我的LINQ To SQL对象:

public static T CloneObjectGraph<T>(this T obj) where T : class 
{
    var serializer = new DataContractSerializer(typeof(T), null, int.MaxValue, false, true, null);
    using (var ms = new System.IO.MemoryStream())
    {
        serializer.WriteObject(ms, obj);
        ms.Position = 0;
        return (T)serializer.ReadObject(ms);
    }
}

但是当我携带没有加载所有引用的对象时,在使用DataLoadOptions进行qyuerying时,有时会抛出对象处理异常,但事情是我 不要求未加载的引用(null)。

e.g。我有许多引用的客户,我只需要继续存储地址参考EntityRef&lt;&gt;我不加载任何其他东西。但是当我克隆对象时,这个异常迫使我加载所有的EntitySet&lt;&gt;使用Customer对象的引用,这可能太多并且降低了应用程序的速度。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

根据我的经验,如果可能的话,最好不要将LINQ序列化为SQL对象。而是使用数据传输对象(DTO)。它们只包含数据,并且没有难以序列化DataContext的引用和隐藏连接。通过这种方式,可以很容易地对它们进行序列化,并且只序列化您需要序列化的内容。

答案 1 :(得分:0)

假设您有一个客户,并有一些订单。

  • 如果您使用LoadOptions.LoadWith<Customer>(c => c.Orders),则会获得客户并填充Customer.Orders EntitySet
  • 如果不这样做,您将获得一个客户和一个懒惰的可加载Customer.Orders EntitySet。任何枚举Orders属性的尝试都会导致DataContext加载此客户的订单。

现在您拥有了Customer,您可以按原样处理DataContext(最好使用using个参数)。

在那之后的一段时间,你会序列化。序列化代码枚举Orders属性。加载这些订单的DataContext消失了,你就会收到错误。

结帐EntitySet.IsDeferredEntitySet.HasLoadedOrAssignedValues


我不是百分之百地确定解决方案,但我会尝试像下面这样的重手:

if (!c.Orders.HasLoadedOrAssignedValues)
{
  c.Orders = null;
}

作为序列化的前期步骤。任何惰性EntitySet必须与Customers断开连接。