0

我有这个扩展方法来克隆我的 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 查询时,有时它会抛出对象已处理的异常,但问题是我不要求未加载的引用(null)。

例如,我有很多引用的客户,我只需要保存地址引用 EntityRef<> 并且我不加载任何其他内容。但是,当我克隆对象时,此异常迫使我使用 Customer 对象加载所有 EntitySet<> 引用,这可能太多并减慢应​​用程序速度。

有什么建议么?

4

2 回答 2

1

根据我的经验,如果可能,最好不要将 LINQ 序列化为 SQL 对象。而是使用数据传输对象 ( DTO )。它们将只包含数据,并且不难序列化引用和隐藏到DataContext. 这样就很容易序列化它们,只序列化你需要序列化的东西。

于 2010-06-16T12:05:26.830 回答
0

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

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

现在您有了客户,您可以按应有的方式处理 DataContext(最好使用using声明)。

之后的一段时间,你进行序列化。序列化代码枚举 Orders 属性。加载这些订单的DataContext那个已经消失了,你得到了错误。

查看EntitySet.IsDeferredEntitySet.HasLoadedOrAssignedValues


我不是 100% 确定解决方案,但我会尝试一些重手的东西,比如:

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

作为序列化的前一步。任何惰性实体集都必须与客户断开连接。

于 2010-06-16T11:40:35.297 回答