9

EF では、プリミティブのリスト (リスト) がある場合、テーブルに対して「結合」するのは簡単です。

var ids = int[]{1,4,6}; //some random values
var rows = context.SomeTable.Where(r => ids.Contains(r.id))

これは、複数の列で結合したい瞬間にはるかに複雑になります。

var keys = something.Select(s => new { s.Field1, s.Field2 })
var rows = context.SomeTable.Where(r => keys.Contains(r => new { s.Field1, s.Field2 })); // this won't work

参加する 2 つの方法を見つけましたが、どちらも素晴らしいものではありません。

  1. テーブル全体を吸い込み、他のデータに基づいてフィルタリングします。(テーブルが非常に大きい場合、これは遅くなります)
  2. キーごとにテーブルにクエリを実行します(取得する行数が適切な場合、これは遅くなります)

時々、私が作ることができた妥協は、変更された #1: かなり一意のキーに基づいてテーブルのサブセットを取得することです

var keys = something.Select(s => s.Field1)
var rows = context.SomeTable.Where(r => keys.Contains(s.Field1)).ToList();
foreach (var sRow in something)
{
    var joinResult = rows.Where(r => r.Field1 == sRow.Field1 && r.Field2 == sRow.Field2);
    //do stuff
}

しかし、これでもあまりにも多くのデータを引き戻す可能性があります。

テーブル値のパラメーターを ADO.Net に誘導する方法と、OR で結合された一連の .Where() 句を作成する方法があることは知っています。魔法の弾丸を持っている人はいますか?

4

4 に答える 4

1

.Contains() の代わりに、内部結合を使用してそのように「フィルター」するのはどうですか。

from s in context.SomeTable
join k in keys on new {k.Field1, k.Field2} equals new {s.Field1, s.Field2}

上記は誤字脱字があるかもしれませんが、ご了承ください...

于 2013-12-04T15:57:41.620 に答える
1

まったく同じ問題が発生し、思いついた解決策は次のとおりです。

  • 単純: ローカル レコードごとに個別のクエリを実行する
  • よりスマート: 一意の Filed1 値と一意の Fiels2 値の 2 つのリストを作成し、2 を使用したクエリに式が含まれていると、正確ではない可能性があるため、結果を 2 倍にする必要があります。

次のようになります。

 var unique1 = something.Select(x => x.Field1).Distinct().ToList();
 var unique2 = something.Select(x => x.Field2).Distinct().ToList();
 var priceData = rows.Where(x => unique1.Contains(x.Field1) && unique2.Contains(x.Field2));
  • 次は、BulkSelect と呼ばれる私自身のソリューションです。その背後にあるアイデアは次のようなものです。

    • 直接 SQL コマンドを使用して一時テーブルを作成する
    • SELECT コマンドのデータをその一時テーブルにアップロードします
    • EF によって生成された SQL を傍受して変更します。

私は Postgres 用にしましたが、これは MSSQL に移植する必要があるかもしれません。これはここでうまく説明されており、ソースコードはここにあります

于 2017-11-01T15:08:30.427 に答える
0
var rows = 
from key in keys
join thingy in context.SomeTable
on 1 = 1
where thingy.Field1 == key && thingy.Field2 == key
select thingy

動作し、適切な SQL を生成する必要があります

于 2013-12-04T16:33:15.600 に答える