18

これは私のコードです:

string queryString = "Marco".ToLower();
utenti = db.User.Where(p => 
        queryString.Contains(p.Nickname.ToLower()) ||
            queryString.Contains(p.Nome.ToLower()) ||
            queryString.Contains(p.Cognome.ToLower())).ToList();

しかし、私は得る:

String.Contains メソッドでは、クライアントで評価できる引数のみがサポートされています。

なんで?使えないの.Contains()

4

2 に答える 2

38

試してみてください.IndexOf。できないのは LINQ ではなく、できないContainsのは LINQ to Entities と LINQ to SQL です。

string queryString = "Marco";
utenti = db.User.Where(p => 
    queryString.IndexOf(p.Nickname, StringComparison.OrdinalIgnoreCase) >= 0 ||
        queryString.IndexOf(p.Nome, StringComparison.OrdinalIgnoreCase) >= 0 ||
        queryString.IndexOf(p.Cognom, StringComparison.OrdinalIgnoreCasee) >= 0)
.ToList();

なんで?

LINQ は遅延実行を使用します。これは、何かを実行する前に、クエリ結果を反復処理する必要があるまで待機することを意味します。LINQ には主に 3 つのタイプがあります。

  1. LINQ to Objects -IEnumerable既にヒープ上にある場合。
  2. LINQ to Entities - Entity Framework を使用してデータベースにクエリを実行する場合。
  3. LINQ to SQL - LINQ to SQL を使用してデータベースにクエリを実行する場合。

2 番目の 2 のコンテキストでの遅延実行とは、結果をforeachブロックに列挙するか.ToList.ToArray、 などの列挙メソッドを呼び出すまで、クエリがデータベースで実行されないことを意味します。それまでは、クエリは式ツリーとして格納されます。メモリー。

db.Userメモリ内のコレクションである場合、クエリはピーチで機能します。ただし、データがデータベースにある場合、LINQ to Entities (または LINQ to SQL) は、式ツリーを「ストア式」と呼ばれるものに変換する必要があります。これは、「LINQ 式を SQL に変換する」という空想的な話です。

ここで、クエリに使用したいカスタム C# アルゴリズムがあり、次のようにしたとします。

var result = db.User.Where(x => MyCustomMethod(x));

現在、LINQ to Entities で C# コードを SQL クエリ (ストア式) に変換する方法はありません。これは、日常的に使用する他の多くの C# メソッドと同じです。.ToLowerまた、.ToUpper.StartsWith、 、 などもサポートしていません.EndsWith。ストア式に変換できる C# メソッドの数には限りがあり、.IndexOfたまたまそのうちの 1 つにすぎません。

ただし、ストア式でサポートされていないのは、ここで説明している文字列オブジェクトのContainsメソッドのみであることに注意してください。LINQ to Entities は s をサポート.ContainsしていIEnumerableます。以下は有効であり、LINQ to Entities で機能します (LINQ to SQL についてはわかりません)。

var idsIWantToFind = new[] { 1, 2, 3 };
var users = db.Where(x => idsIWantToFind.Contains(x.UserId));

上記は、SQLWHERE UserId IN (1, 2, 3)述語を実行するのと同じです。

于 2013-11-05T14:32:15.297 に答える
-3

問題は入力の優先順位です。例えば:

a.Contains(b); または b.Contains(a);

次のように書いた方がよいでしょう:

p.Nickname.Contains(queryString) ...

それ以外の

queryString.Contains(p.Nickname) ...
于 2015-08-22T20:41:18.180 に答える