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) は要求しません。

たとえば、多くの参照を持つ Customer があり、Address 参照 EntityRef<> をメモリに保持する必要があるだけで、他には何もロードしません。しかし、オブジェクトのクローンを作成している間、この例外により、すべての EntitySet<> 参照を Customer オブジェクトでロードする必要があり、負荷が大きすぎてアプリケーションの速度が低下する可能性があります。

助言がありますか?

4

2 に答える 2

1

私の経験では、可能であれば LINQ to 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この顧客の注文をロードします。

Customer を取得したので、必要に応じて DataContext を破棄します (ステートメントを使用することをお勧めしますusing)。

その後しばらくして、シリアル化します。シリアル化コードは Orders プロパティを列挙します。これらのDataContext注文をロードする はなくなり、エラーが発生します。

EntitySet.IsDeferredEntitySet.HasLoadedOrAssignedValuesを確認してください。


私は解決策を100%確信しているわけではありませんが、次のような難しいことを試してみます:

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

シリアル化の前段階として。怠惰な EntitySet は、Customers から切断する必要があります。

于 2010-06-16T11:40:35.297 に答える