0

私は自分のプロジェクトの1つでLINQ2SQLを使用しており、顧客-> Documents1、Documents2、Documents3、Address、Invoicesなどの多くの関係があります。

LoadWith(p => p.Documents1)... etcを使用する場合、パフォーマンスの問題があります。これらの多数の関係がすべてメモリのリストにロードされている2000人の顧客を想像してみてください。

ドキュメント->顧客の逆は、関係が軽いほど問題ではありません。

したがって、すべてのLoadWithを削除して、Customer->Addressの関係をそのままにしておくようにします。ここで、Document1を開いてから顧客を開くと、顧客をシリアル化するときにオブジェクトの破棄の例外が発生します。serializeメソッドは基本的にこの例外をスローします。

シリアル化方法:

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);
            }
        }

私が顧客を獲得する方法:

public List<Customer> GetCustomers()
{
    using (MyDataContext db = new MyDataContext(MyDataContextManager.ConnectionString))
    {
        DataLoadOptions dlo = new DataLoadOptions();
        dlo.LoadWith<Customer>(p => p.Address);
        dlo.LoadWith<Customer>(p => p.Documents1);
        dlo.LoadWith<Customer>(p => p.Documents2);
        dlo.LoadWith<Customer>(p => p.Documents3);
        dlo.LoadWith<Customer>(p => p.Documents4);
        dlo.LoadWith<Customer>(p => p.Documents5);
        dlo.LoadWith<Customer>(p => p.Documents6);
        dlo.LoadWith<Customer>(p => p.Documents7);
        dlo.LoadWith<Customer>(p => p.Documents8);
        dlo.LoadWith<Customer>(p => p.Documents9);
        dlo.LoadWith<Customer>(p => p.Documents10);
        dlo.LoadWith<Customer>(p => p.Documents11);

        db.LoadOptions = dlo;

        return db.Customers.ToList();
    }
}

アドレス関係を除くすべてのLoadWithを削除したい。このエラーが常に再現されるとは限らないのですが、場合によっては見つかりませんでした。

DataContractSerializerコンストラクターの変更を推測できましたが、正しく理解できません。

助けていただければ幸いです。

4

1 に答える 1

1

clone メソッドがオブジェクトのすべての子プロパティにアクセスしようとするため、エラーが発生しています。LoadWith<>() ステートメントがある場合、それらの子プロパティは既にデータベースから取得されており、メモリ内で使用できます。LoadWith<>() ステートメントを削除すると、プロパティはデータベースからオブジェクトを遅延ロードしようとします。既にデータベース接続を閉じているため、これらのプロパティを読み込むことができません (エラーが発生します)。

解決策は、オブジェクトのディープ コピーを実行して何を達成しようとしているかによって異なります。そのディープ コピーが実際に子プロパティ (DocumentsXX) を持つ必要がある場合は、LoadWith<>() ステートメントをそのままにしておくか、プロセス中にデータベース接続を開いたままにする必要があります (2 つのうち、LoadWith< を残します)。 >() ステートメントは、DB へのアクセスを最小限に抑え、とにかく同じ量のメモリを使用することになるため、おそらくより良いオプションです)。ディープ コピーにこれらのプロパティを含める必要が本当にない場合は、現在のディープ クローン プロセスを、それらのプロパティを無視できる on に置き換える必要があります (手動で作成されたディープ クローンまたはカスタマイズされたシリアライゼーション プロセスのいずれかが機能します)。

于 2010-11-04T16:19:24.407 に答える