2

正しいクエリを作成するのに助けが必要です。Employeesテーブルがあります。すべての従業員のリストを取得する必要があります。EENO(従業員ID)には、提供された部分的な従業員IDの配列からの文字列が含まれています。

このコードを使用すると

// IEnumerable<string> employeeIds is a collection of partial Employee IDs
IQueryable<Employee> query = Employees;
foreach (string id in employeeIds)
{
    query = query.Where(e => e.EENO.Contains(id));
}
return query;

私は次のようなものを手に入れます:

SELECT * 
FROM Employees 
WHERE EENO LIKE '%1111111%' 
  AND EENO LIKE '%2222222%' 
  AND EENO LIKE '%3333333%' 
  AND EENO LIKE '%4444444%' 

これは意味がありません。 結果のSQLで「AND」の代わりに「OR」が必要です。

ありがとうございました!

アップデート

PredicateBuilderを使用して作成したこのコードは、これらの従業員を含める必要がある場合に完全に機能します。

var predicate = PredicateBuilder.False<Employee>();
foreach (string id in employeeIds)
{
    var temp = id;
    predicate = predicate.Or(e => e.EENO.Contains(temp));
}
var query = Employees.Where(predicate);

今、私はこれらの従業員を除外するために反対のコードを書く必要があります、ここにありますが、それは機能していません:生成されたSQLは完全に奇妙です。

var predicate = PredicateBuilder.False<Employee>();
foreach (string id in employeeIds)
{
    var temp = id;
    predicate = predicate.And(e => !e.EENO.Contains(temp)); // changed to "And" and "!"
}
var query = Employees.Where(predicate);
return query;

次のようなSQLWhere句を生成することになっています。

WHERE EENO NOT LIKE '%11111%'
       AND NOT LIKE '%22222%'
       AND NOT LIKE '%33333%'

しかし、それは起こっていません

生成されるSQLは次のとおりです:http://i.imgur.com/9MDP7.png

どんな助けでも大歓迎です。ありがとう。

4

4 に答える 4

3

の代わりにforeach、IQueryableを1回ビルドするだけです。

query = query.Where(e => employeeIds.Contains(e.EENO));
于 2012-11-08T16:09:00.247 に答える
2

http://www.albahari.com/nutshell/predicatebuilder.aspxを見てみましょう。これは、Orクエリを構築するための優れた方法であり、LinqPadを作成した人によって作成されています。上記のリンクにも使用例があります。

于 2012-11-08T16:09:41.547 に答える
1

私はあなたが使うことができると信じていますAny()

var query = Employees.Where(emp => employeeIds.Any(id => id.Contains(emp.EENO)));
于 2012-11-08T17:20:06.650 に答える
1

述語ビルダーを使用したくない場合、他の唯一のオプションは、中間クエリで各コレクションをUNIONすることです。

// IEnumerable<string> employeeIds is a collection of partial Employee IDs
IQueryable<Employee> query = Enumerable.Empty<Employee>().AsQueryable();
foreach (string id in employeeIds)
{
    string tempID = id;
    query = query.Union(Employees.Where(e => e.EENO.Contains(tempID));
}
return query;

また、クロージャルールは述語を破り、最後の基準でのみフィルタリングされることになることにも注意してください。そのため、ループtempID内に変数があります。foreach

編集:これがあなたが遭遇したすべての問題の概要です:

ANDSの代わりにORを生成する

PredicateBuilderを使用して完了しました。

最後の述語のみが適用されています

内部ループで一時変数を割り当てることで対処されます(クロージャールールによる)

除外述語が機能しない

正しいベースケースから始める必要があります。sを使用する場合は、最初に大文字小文字を区別ORする必要があります。そうすれば、false少なくとも1つの述語が一致するレコードのみを含めることができます(それ以外の場合は何も返されません)。これは、評価のために基本ケースを無視する必要があるためです。言い換えればfalse || predicate1 || predicate2 || ...、実際にはpredicate1 || predicate2 || ...、述語のリストで少なくとも1つの真を探しているからです(そして、構築するためのベースが必要なだけです)。逆のことがケースに当てはまりますAND。評価の目的で「無視」されるようにすることから始めtrueますが、それでもベースケースが必要です。言い換えればtrue && predicate1 && ...、:はと同じpredicate1 && ...です。それがあなたの最後の問題に対処することを願っています。

于 2012-11-08T17:26:04.520 に答える