2017-04-03 11 views
2

10.000回(現実的な数値)同じクエリを呼び出さないようにしてクエリ呼び出しを最適化したい。C#Linq multi OR

var myObject= _db.myObject.FirstOrDefault(x => x.property1 == param1 && x.property2 == param2 && x.property3 == 3); 

だから私は

は、関数にmyOtherObjectのリストを渡すことができます思いました。 myOtherObjectには通常param1,2および3を満たすフィールドが含まれます。

通常のクエリでは、foreach内に文字列を作成して連結します。このように:

  // WHERE (property1 = param1 && property2 = param2 && property3 = param3) OR (property1 = param1 && property2 = param2 && property3 = param3) OR (property1 = param1 && property2 = param2 && property3 = param3) 

どのようにして(可能な場合)LINQで達成できますか。 が、それは、複数の論理和に

をCONCATすることは可能です勿論、私はいずれかと連結を試み、それが作成し、ステートメント(論理的に)ので、どこだが、それdidntの仕事試してみました。

コンテキスト

私は自分のデータベース内のオブジェクトをしました。私はデータベース内の別のオブジェクトと比較する必要があります。私は読み取り専用のアクセス権しか持っていません。私は3つのパラメータの組み合わせで2つのオブジェクトを一致させることができます。

INPUT

一覧

(一致させるために必要な3つのフィールドを持っている)をObjectAのOUTPUT

私はをしたい他の(読み込み専用)データベースから一致するオブジェクトのリストを返します。

+1

DBにパラメータ化されたストアドプロシージャを作成して使用しないのはなぜですか?これは完璧なユースケースです。 – Robert

+0

私はこのデータベースからしか読むことができません。ストアドプロシージャが受け入れられるかどうかはわかりません。アイデアありがとう! – JochemQuery

+0

申し訳ありませんが、出力として何を入力しているかはわかりませんが、入力した内容に常に焦点を当ててみてください。 –

答えて

0

:私はこの使用してLINQは

public async Task<List<MyObject>> GetMyObjectByListOfStrings(List<string> search) 
    { 
     var myObjects = await _db.Entity.Where(x => search.Contains(x.param1+ x.param2+ x.param3)).ToListAsync(); 
     return myObjects; 
    } 

より良いオプション、変更する必要がありますデザインや代わりに固定されなければならない実際の問題は、おそらくありますが含まれています解決しました。

1

System.Linq.Expressions APIsを使用してLINQ用の式を作成することもできますが、ターゲットデータベースの個々の属性の選択性によっては、より簡単な方法が有効です。

まず、他のセットはメモリ内にもある場合は、メモリ内のオブジェクトの集合にマッチを見つける作業は非常に簡単であることに注意してください。

// Type parameters of Tuple<,,> depend on the types of Prop1..Prop3 
var expect = new HashSet<Tuple<string,string,string>>(
    targetList.Select(item => Tuple.Create(item.Prop1, item.Prop2, item.Prop3)) 
); 
var matches = sourceList 
    .Where(item => expect.Contains(Tuple.Create(item.Prop1, item.Prop2, item.Prop3))) 
    .ToList(); 

上記のデータベース検索では動作しませんので、 「偽陽性」

  • フィルターうち、上記の手法を用いて偽陽性を持つすべての可能な一致を見つけるために、データベースを読む

    1. :、二段階のアプローチを検討してください。

    あなたはこのように、個々のパラメータを照会することにより、偽陽性と項目のリストを取得できます。

    var p1List = targetList.Select(item => item.Prop1).ToList(); 
    var p2List = targetList.Select(item => item.Prop2).ToList(); 
    var p3List = targetList.Select(item => item.Prop3).ToList(); 
    var preliminary = dbContext.BigTable 
        .Where(item => p1List.Contains(item.Prop1) 
           && p2List.Contains(item.Prop2) 
           && p3List.Contains(item.Prop3)) 
        .AsEnumerable(); 
    

    このアプローチは限りDBクエリが10未満にダウンリストParesにおけるように動作しますメモリ内のクエリはCPU使用率(効率はO(M + N)、Mは偽陽性のリストのサイズ、Nはターゲットリストのサイズ将来的にこの問題に直面して人々のために

  • +0

    情報ありがとうございました! – JochemQuery

    +1

    @JochemQueryあなたは大歓迎です!あなたが試してみる機会があれば、私は興味があります。 – dasblinkenlight

    +0

    私は今日、インターンシップの代わりに試験を受けました(私はそれを渡しました:))ので、私はまだチェックしませんでした。私はこのアプローチを試すときはわかりませんが、私はここで更新します – JochemQuery