web-dev-qa-db-ja.com

アクセントとケースを無視するLINQ

アクセントと大文字小文字を無視してWhereメソッドを使用してLINQで要素をフィルタリングする最も簡単な方法は何ですか?

これまでのところ、プロパティのメソッドを呼び出すことでケーシングを無視することができましたが、すべての要素に対して同じメソッドを呼び出すため、これは良い考えではないと思います(右?)。

これが私がこれまでに得たものです:

var result = from p in People
             where p.Name.ToUpper().Contains(filter.ToUpper())
             select p;

これが良い習慣であり、アクセントを無視する最も簡単な方法であるかどうかを教えてください。

27
Smur

大文字と小文字とアクセント(発音区別符号)を無視するには、最初に次のような拡張メソッドを定義できます。

    public static string RemoveDiacritics(this String s)
    {
        String normalizedString = s.Normalize(NormalizationForm.FormD);
        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < normalizedString.Length; i++)
        {
            Char c = normalizedString[i];
            if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                stringBuilder.Append(c);
        }

        return stringBuilder.ToString();
    }

文字列比較でアクセント付き文字を無視する から変更)

これで、クエリを実行できます。

string queryText = filter.ToUpper().RemoveDiacritics();

var result = from p in People
         where p.Name.ToUpper().RemoveDiacritics() == queryText
         select p;

これは、C#でコレクションを反復処理するだけの場合は問題ありませんが、LINQ to SQLを使用している場合は、LINQクエリで非標準のメソッド(拡張メソッドを含む)を避けることをお勧めします。これは、コードを有効なSQLに変換できないため、パフォーマンスが最適化されたSQLServerで実行できるためです。

LINQ to SQL内のアクセントを無視する標準的な方法はないように思われるため、この場合、検索するフィールドタイプを大文字と小文字を区別せず、アクセントに依存しないように変更することをお勧めします(CI_AI)。

あなたの例で:

ALTER TABLE People ALTER COLUMN Name [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AI

これで、クエリはアクセントと大文字小文字を無視するはずです。

フィールドの一意の制約を一時的に削除する必要があることに注意してくださいbefore上記のクエリを実行します。例:.

ALTER TABLE People DROP CONSTRAINT UQ_People_Name

これで、LINQクエリは単純に次のようになります。

var result = from p in People
         where p.Name == filter
         select p;

関連する質問を参照してください ここ

47
Dunc

照合順序の変更:

ALTER TABLE dbo.MyTable 
ALTER COLUMN CharCol varchar(10)**COLLATE Latin1_General_CI_AS** NOT NULL;

アクセントを無視して比較できるコードを次に示します。

文字列比較でアクセント付き文字を無視します

私はコードをコピーしないという良識を持っているので、作者は彼の答えの担当者を得ることができます。今、あなたの質問に答えます:

そのコードを取得して、次のように使用します。

var result = from p in People
             where p.Name.ToUpper().Contains(RemoveDiacritics(filter.ToUpper()))
             select p;

そのコードを拡張メソッドに変えることさえできます。私が持っています :)

0
Adrian Carneiro

データベース全体の照合順序を変更するDuncのソリューションに続いて、インデックス、キーなどを扱う完全なチュートリアルがあります。

https://www.codeproject.com/Articles/302405/The-Easy-way-of-changing-Collat​​ion-of-all-Database

(最初にすべてのコメントを必ず読んでください。)

0
LePatay