【问题标题】:Clone LINQ To SQL object Extension Method throws object dispose exception克隆 LINQ To SQL 对象扩展方法引发对象处置异常
【发布时间】:2010-06-15 21:22:39
【问题描述】:

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

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

有什么建议吗?

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 我不太清楚你所说的 DTO 是什么意思,如果可以的话,请举个例子。谢谢你的回答。
    • 我添加了一个解释数据传输对象的维基百科链接,但它们基本上没有什么特别之处。它们是 POCO(普通的旧 CLR 对象),在您的情况下是可序列化的 POCO。这是我写的关于 DTO 的 SO 答案。我想这也回答了你的问题:stackoverflow.com/questions/2785506/…
    【解决方案2】:

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

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

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

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

    查看EntitySet.IsDeferredEntitySet.HasLoadedOrAssignedValues


    我不是 100% 确定解决方案,但我会尝试一些严厉的方法,例如:

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

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

    【讨论】:

    • 我认为我在应用程序中达到的最佳步骤是加载我可能需要的大部分参考资料,并在我的下一个应用程序中使用 PLinqo 或开始学习 EF 4。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 2020-05-01
    • 1970-01-01
    相关资源
    最近更新 更多