LINQ содержит нечувствительный к регистру

Этот код чувствителен к регистру, как сделать регистр нечувствительным к регистру?

public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
    return this.ObjectContext.FACILITY_ITEM.Where(fi => fi.DESCRIPTION.Contains(description));
}

Ответ 1

fi => fi.DESCRIPTION.ToLower().Contains(description.ToLower())

Ответ 2

Если запрос LINQ выполняется в контексте базы данных, вызов Contains() отображается на оператор LIKE:

.Where(a => a.Field.Contains("hello"))  становится Field LIKE '%hello%'. Оператор LIKE по умолчанию не зависит от регистра, но его можно изменить с помощью изменения сортировки столбца.

Если запрос LINQ выполняется в контексте .NET, вы можете использовать IndexOf(), но этот метод не поддерживается в LINQ to SQL.

LINQ to SQL не поддерживает методы, которые принимают параметр CultureInfo как, возможно, потому, что он не может гарантировать, что сервер SQL обрабатывает культуры так же, как .NET. Это не совсем так, потому что оно поддерживает StartsWith(string, StringComparison).

Однако он, похоже, не поддерживает метод, который оценивает значение LIKE в LINQ to SQL, а также нечувствительное к регистру сравнение в .NET, что делает невозможным непротиворечивость Contains()./p >

Ответ 3

Предположим, что мы работаем со строками здесь, здесь другое "элегантное" решение с использованием IndexOf().

public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
    return this.ObjectContext.FACILITY_ITEM
        .Where(fi => fi.DESCRIPTION
                       .IndexOf(description, StringComparison.OrdinalIgnoreCase) != -1);
}

Ответ 4

В принятом ответе здесь не упоминается факт, что если у вас есть нулевая строка, ToLower() выдает исключение. Более безопасный способ:

fi => (fi.DESCRIPTION ?? string.Empty).ToLower().Contains((description ?? string.Empty).ToLower())

Ответ 5

С помощью С# 6.0 (который позволяет использовать функции с выражением тела и нулевого распространения) для LINQ to Objects, это можно сделать в одной строке, подобной этой (также проверяющей на null):

public static bool ContainsInsensitive(this string str, string value) => str?.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0;

Ответ 6

IndexOf лучше всего работает в этом случае

return this
   .ObjectContext
   .FACILITY_ITEM
   .Where(fi => fi.DESCRIPTION.IndexOf(description, StringComparison.OrdinalIgnoreCase)>=0);

Ответ 7

Вы можете использовать string.Compare

    lst.Where(x => string.Compare(x,"valueToCompare",StringComparison.InvariantCultureIgnoreCase)==0);

если вы просто хотите проверить наличие, используйте "Any"

  lst.Any(x => string.Compare(x,"valueToCompare",StringComparison.InvariantCultureIgnoreCase)==0)

Ответ 8

public static bool Contains(this string input, string findMe, StringComparison comparisonType)
{
    return String.IsNullOrWhiteSpace(input) ? false : input.IndexOf(findMe, comparisonType) > -1;
}

Ответ 9

Используйте метод Enumerable.Contains(IEnumerable, TSource, IEqualityComparer), используя один из сопоставлений StringComparer.___ IgnoreCase (либо Ordinal, InvariantCulture, либо CurrentCulture).

public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
    return this.ObjectContext.FACILITY_ITEM.Where(
        fi => fi.DESCRIPTION.Contains(description, StringComparer.OrdinalIgnoreCase)
    );
}

Ответ 10

StringComparison.InvariantCultureIgnoreCase просто сделайте эту работу за меня:

.Where(fi => fi.DESCRIPTION.Contains(description, StringComparison.InvariantCultureIgnoreCase));

Ответ 11

Используйте Метод String.Equals

public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
    return this.ObjectContext.FACILITY_ITEM
           .Where(fi => fi.DESCRIPTION
           .Equals(description, StringComparison.OrdinalIgnoreCase));
}