2016-09-06 17 views
2

私は一つ以上のリストのパス述語A()、およびなしパス述語B()項目かどうかを確認する必要があるのLINQでクエリを書いているがある場合にのみ。 LinqからSQLを有効にするには、単一のクエリである必要があります。LINQの - すべてのチェックが、少なくとも1つの

1. [ a, a ] => true 
2. [ a ] => true 
3. [ a, b ] => false 
4. [ b, b ] => false 
5. [ b ] => false 
6. [ ]  => false 

私は次のことを試してみたが、それぞれが、彼らは失敗する特定の状況があります:

// Fails in case 6 
MyList.All(x => A(x) && !B(x)); 

// Fails in case 3 
MyList.Where(x => !B(x)).Count(x => A(x)) > 0; 

// This works, but it's not a single query anymore 
MyList.All(x => A(x) && !B(x)) && Mylist.Count() > 0; 
aパスが A()bパスが B()を述語述語ところ、以下のように、以下のリストの結果がでなければなりません

私がここに必要なのは、すべてに相当するものだと思っていますが、空のリストに対してはfalseを返します。たとえば、これはすべてのケースで合格となります:

MyList.AllButReturnFalseIfListIsEmpty(x => A(x) && !B(x)); 

どうすればいいですか?

答えて

1

を私はあなたにLinq All on empty collectionに私の答えのようなものを示唆している:

var result = MyList.Max(x => B(x) ? (int?)2 : A(X) ? (int?)1 : (int?)0) == 1; 

をそれはMax<int?>方法が

をどのように機能するかを利用

(A)シーケンスが空の場合は、nullを返します (B)Bと一致する少なくとも一つの元素が存在する場合、結果は2
(C)少なくとも一つの元素Bに一致し、Aに一致しないがあれば、結果は1
(D)であり、そうでなければ結果0

ですので、(C)のケースを確認します。

+0

賢い!私はこれが受け入れられた答えと同じくらい簡単であるとは確信していませんが、簡潔さの完全な印です。どちらもかなり外です。 –

+0

ありがとうございます。私は@dasblinkenlightから今日何かを学んだので、好奇心から、 'Aggregate'クエリはSQLに変換されます(私はかなり' Max'がそうしていると思います)? –

+1

Nevermind。私が推測しているように、EFは「集約」をサポートしていません。 –

0

これを試してみてください:評価後のいずれかの項目があるかどう

MyList.All(x => MyList.Any() && A(x) && !B(x)); 
+0

これは、EntityFramework内のLinq to SQLクエリの一部です。したがって、リストとして変数としてアクセスすることはできません。これはすべて1つの表現です(例: - 'dbContext.MyTable.Any(x => x.thing == true); ' –

0

なぜあなたはちょうどチェックしませんか?

MyList.Where(x => A(x) && !B(x)).Any(); 
+0

これは、リストに述語' B()'を渡す値が含まれている場合にtrueを返します。 –

+0

@AlfieWoodland oopsは、意味があります。 – sam

2

あなたはこのようにそれを行うことができます。以下のように

var result = MyList 
    .Select(x => B(x) ? -1 : (A(x) ? 1 : 0)) 
    .Aggregate(0, (p, v) => v == -1 || p == -1 ? -1 : p + v) > 0; 

クエリが動作します:Btrueとき

  • Select-1を作り出します。 A
  • Aggregateチェック-1, 0, 1から番号のリストfalseの場合Atrue0であれば、それ以外の場合は1を生成します。 -1が表示されている場合、集計結果は-1です。それ以外の場合は、集計の結果は正の値の合計になります。
  • 最後に比較すると、Aが少なくとも1つあり、Bがありません。
+0

"* LinqをSQL *にするためには、単一のクエリである必要があります。" –

+1

@IvanStoev It *は単一クエリです。 – dasblinkenlight

+0

私は一度これを試してみるつもりです。 –

0

空コレクションでfalseを返す場合は、All()を使用しないでください。 documentationを見てみましょう:

真のシーケンスが空の場合は、ソースシーケンスのすべての要素が 指定された述語、またはでテストに合格した場合、それ以外の場合はfalseです。

代わりに、私はこのような何かしようとするだろう:

MyList.Where(x => A(x) && !B(x)).Any(); 
+0

これは、述語 'B()'を渡す値を含むリストに対して真を返します。 –

関連する問題