1

linq to sql を介してリンク サーバーでの結合をシミュレートしています。私の質問は、linqtosql が y.Xstatuses のすべての行をメモリに取り込み、結合を行っているように見えるということです。これが真の場合、SQL サーバーにすべてのメモリを保持するにはどうすればよいですか (そして、クロス データ コンテキスト結合操作を実行します)。

var x = new fooDataContext();
var y = new barDataContext();

var allXNotDeleted = (from w in x.CoolTable
                      where x.IsDeleted != false).ToList();//for our demo this returns 218 records

var allXWithCompleteStatus = (from notDeleted in allXNotDeleted
                              join s in y.XStatuses on notDeleted.StatusID equals s.StatusID
                              where s.StatusID == 1
                              select notDeleted).Tolist();// insert massive memory gobbler here

return allXwithCompleteStatus;

編集:Kevinbabcockのアイデアを実装しようとしています

    using (x = new fooDataContext())
    using (var y = new barDataContext())
    {

        var n = (from notDeleted in x.GetTable<CoolTable>()
             join z in y.GetTable<Xstatus>() on x.StatusID equals z.StatusID
             where z.StatusID == 1 and x.IsDeleted != false
             select x).ToList();

    }

これでも、クロス コンテキスト クエリの例外がスローされます。

4

3 に答える 3

3

データベースに対してクロス データ コンテキスト クエリを直接実行することはできません。レコードセット (ToList()) の 1 つをメモリにフェッチすると、結合されたもう 1 つのレコードセットが強制的にメモリ内で処理されます。

SQL サーバーですべてを実行する場合は、すべてのエンティティを同じ DataContext に含める必要があります。

于 2013-01-25T15:44:06.547 に答える
0

ToList()電話をかけないでくださいallXNotDeleted。これにより、これらのレコードがメモリ内でXStatuses実体化され、結合を実行するためにテーブル全体もメモリ内で実体化されます。

これを試して:

using(var context = new DataContext(connectionString))
{
    var allXNotDeleted =
        from w in context.GetTable<CoolTable>()
        where x.IsDeleted != false;
    var allXWithCompleteStatus = (
        from notDeleted in allXNotDeleted
        join s in context.GetTable<XStatuses>()
            on notDeleted.StatusID equals s.StatusID
        where s.StatusID == 1
        select notDeleted)
        .ToList();
    return allXwithCompleteStatus;
}

これは、単一のクエリのみを SQL Server に送信し、クエリから返された "notDeleted" 値のみを具体化します。コンテキストから外れたときに適切に呼び出されるDataContextように、インスタンスを using ステートメントでラップすることを忘れないでください。Dispose()

また、でフィルタリングするつもりでしたCoolTableIsDeleted != false?これはIsDeleted == true、削除されたすべてのレコードを結合したいことを示しています (変数の名前 はallXNotDeleted矛盾しているようです)。

編集: 単一のDataContextインスタンスで動作するようにコードを更新しました。これにより、「クエリに別の DataContext への参照が含まれています」というエラーが解消されます。派生クラスを使用していない場合はConnectionString、コンストラクターに渡す必要があります。DataContextDataContext

于 2013-01-25T15:45:30.603 に答える
0

最初から電話ToListしないことをお勧めallXNotDeletedします。これにより、これらのレコードがメモリに取り込まれます。これは、おそらく、2 番目のクエリを実行するときに、他のすべてのデータをメモリに取り込むことを避けることができないことを意味します。

編集:

テーブルが特に大きく、少数の列からのデータのみが必要な場合の追加の注意として、必要のない列のデータベース オブジェクト モデルで を設定できますDelay LoadedTrue

EDIT2:

両方のクエリが異なるコンテキストから来ていることに気付きました。その場合、ストアド プロシージャを作成し、コンテキストの 1 つからそれを呼び出すことをお勧めします。sproc は、コンテキストのスパンを担当する必要があります。

于 2013-01-25T15:40:52.713 に答える