web-dev-qa-db-ja.com

Entity Frameworkコア-大文字と小文字を区別するか、区別しないかを含む

Entity Frameworkコアの「含む」は、SQLの%like%演算子と同等です。したがって、「次を含む」は大文字と小文字を区別しませんが、大文字と小文字を区別します。 (少なくともpostgresでは????)

以下は、キーワードの正しい大文字小文字を使用した場合にのみ結果を出力します。

context.Counties.Where(x => x.Name.Contains(keyword)).ToList();

何が悪いのですか?

18
001

以前のバージョンのEFコアがこれに該当していました。現在_string.Contains_は大文字と小文字が区別され、sqliteの例ではsqlite関数 `instr() 'にマッピングされます(postgresqlについてはわかりません)。

大文字と小文字を区別しない方法で文字列を比較する場合は、ジョブを実行するDbFunctionsがあります。

_context.Counties.Where(x => EF.Functions.Like(x.Name, $"%{keyword}%")).ToList();
_

@Gertへの更新:

質問の仮定の一部が正しくありません。 _string.Contains_は、efコアバージョン<= 1.0の場合に使用されていたとしても、_LIKE expression_に変換されません(私はそう思います)。

  • SQLServer _string.contains_はCHARINDEX()に変換され、 Oracle および sqliteinstr()に変換されますデフォルトでは大文字と小文字が区別されますUNLESS dbまたは列の照合は別の方法で定義されます(繰り返しますが、私はpostgresqlについては知りません)。
  • すべての場合において、EF.Functions.Like()はSQL LIKE式に変換されます。これは、dbまたは列の照合順序が別の方法で定義されていない限り、デフォルトでは大文字と小文字が区別されません。

つまり、すべては照合に行き着きますが、コードが大文字と小文字を区別する/区別しない検索に、上記の方法のどれを使用するかに応じて影響する可能性があるという点で-私が間違っている場合は修正してください。

今、私は完全に最新ではないかもしれませんが、EFコアの移行はDB照合を自然に処理するとは思わず、テーブルを手動で作成していない場合は、デフォルトの照合になります(sqliteと私は大文字と小文字が区別されます)正直なところ、他の人にはわかりません)。

元の質問に戻ると、将来のリリースで3ではない場合でも、この大文字と小文字を区別しない検索を実行するには、少なくとも2つのオプションがあります。

  1. これを使用してDbContext.OnModelCreating()を使用して作成時に列の照合を指定します trick
  2. _string.Contains_をEF.Functions.Like()に置き換えます
  3. または、有望な機能が discussion にあるのを待つ:EF.Functions.Collate() function
20
DarkUrse

私の答えはNpgSQLに関係します。

  1. PostgreSQLのEF.Functions.Like()では大文字と小文字が区別されますが、_Npgsql.EntityFrameworkCore.PostgreSQL_ Assembly にあるEF.Functions.ILike()拡張機能 method を使用できます。

  2. クエリを構築する場所にEntity Framework Assemblyへの参照がない場合、Npgsqlは able であるため、ToLower()メソッドとContains()メソッドの組み合わせを使用できます。 SQLを修正するためのToLower()メソッドの変換

例:

_context.Counties.Where(x => x.Name.ToLower().Contains(keyword.ToLower())).ToList();
_

2番目の方法について注意してください:パフォーマンスの問題があり、エンコーディングに関連する問題が発生する可能性があります。

5
Stas Boyarincev

IQueryable.Whereはデータベースで実行されるため、ほとんどの場合、大文字と小文字は区別されません。

IEnumerable.WhereはC#を使用しますString.Containsなので、大文字と小文字が区別されます。

この回答をお読みください: IEnumerableとIQueryableを返す

4
Kfir Guy

やってみなよ :

あなたはできる Lower caseフィールドと検索値

  context.Counties.Where(x => x.Name.ToLower().Contains(keyword.ToLower())).ToList();

または、Upper Caseフィールドと検索値

context.Counties.Where(x => x.Name.ToUpper().Contains(keyword.ToUpper())).ToList();
1
topcool