1


0

LINQ 2 SQLクエリObjectDisposed例外

私が今日持っていたこれは奇妙なものです。

このクエリはアセンブリメソッドにあります。

        public Order[] SelectAllOrders()
    {
        Order[] orders;
        using (MyDataContext context = new MyDataContext())
        {
            DataLoadOptions dlo = new DataLoadOptions();
            dlo.LoadWith(order => order.OrderDetails);
            context.LoadOptions = dlo;

            orders = context.Orders.Select(p => p).ToArray();
        }
        return orders;
    }

既にToArray()を呼び出し、SQLコマンドを実行し、必要なオブジェクトを提供し、DataOrderインスタンスを必要としない新しいOrder []配列にそれらを提供したとします。 メソッドreturnから取得するOrder []をシリアライズしている間、シリアライザーはDataContextへのアクセスを再試行し、破棄されたオブジェクトにアクセスできない例外を取得します。

using()ステートメントを使用せずに試してみましたが、動作するはずです。 しかし、なぜこの動作が発生するのですか? .ToArray()を呼び出してコンテンツに新しい変数を割り当てているときに、遅延ロードがまだ残っている理由を誰でも説明できますか?

1 Answer


1


`Select(p ⇒ p)`はほとんど達成しません。次のように呼び出すこともできます。

orders = context.Orders.ToArray();

問題について-私は、 `OrderDetails`が実際にロードされていないか、いくつかの_other_データを遅延的にロードしようとしていると思います。 (devセッションで)調査することをお勧めします。

    Order[] orders;
    using (MyDataContext context = new MyDataContext())
    {
        context.Log = Console.Out; // show me
        DataLoadOptions dlo = new DataLoadOptions();
        dlo.LoadWith(order => order.OrderDetails);
        context.LoadOptions = dlo;
        Console.WriteLine("> Calling ToArray");
        orders = context.Orders.ToArray();
        Console.WriteLine("> ToArray complete");

        // TODO: your extra code that causes serialziation, probably
        // involving `DataContractSerializer`

        Console.WriteLine("> Calling Dispose");
    }

これにより、 ToArray`の後で、しかし Dispose() `の前に_起こっている余分なデータベーストリップを見ることができるはずです。 ポイントは、このデータはシリアル化に必要なため、a:データを確実にロードするか、b:シリアル化から除外することです。