我有这个扩展方法来克隆我的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对象的引用,这可能太多并且降低了应用程序的速度。
有什么建议吗?
答案 0 :(得分:1)
根据我的经验,如果可能的话,最好不要将LINQ序列化为SQL对象。而是使用数据传输对象(DTO)。它们只包含数据,并且没有难以序列化DataContext
的引用和隐藏连接。通过这种方式,可以很容易地对它们进行序列化,并且只序列化您需要序列化的内容。
答案 1 :(得分:0)
假设您有一个客户,并有一些订单。
LoadOptions.LoadWith<Customer>(c => c.Orders)
,则会获得客户并填充Customer.Orders EntitySet
。EntitySet
。任何枚举Orders属性的尝试都会导致DataContext
加载此客户的订单。现在您拥有了Customer,您可以按原样处理DataContext(最好使用using
个参数)。
在那之后的一段时间,你会序列化。序列化代码枚举Orders属性。加载这些订单的DataContext
消失了,你就会收到错误。
结帐EntitySet.IsDeferred和EntitySet.HasLoadedOrAssignedValues。
我不是百分之百地确定解决方案,但我会尝试像下面这样的重手:
if (!c.Orders.HasLoadedOrAssignedValues)
{
c.Orders = null;
}
作为序列化的前期步骤。任何惰性EntitySet必须与Customers断开连接。