Ответ 1
fi => fi.DESCRIPTION.ToLower().Contains(description.ToLower())
Этот код чувствителен к регистру, как сделать регистр нечувствительным к регистру?
public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
return this.ObjectContext.FACILITY_ITEM.Where(fi => fi.DESCRIPTION.Contains(description));
}
fi => fi.DESCRIPTION.ToLower().Contains(description.ToLower())
Если запрос 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 >
Предположим, что мы работаем со строками здесь, здесь другое "элегантное" решение с использованием IndexOf()
.
public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
return this.ObjectContext.FACILITY_ITEM
.Where(fi => fi.DESCRIPTION
.IndexOf(description, StringComparison.OrdinalIgnoreCase) != -1);
}
В принятом ответе здесь не упоминается факт, что если у вас есть нулевая строка, ToLower() выдает исключение. Более безопасный способ:
fi => (fi.DESCRIPTION ?? string.Empty).ToLower().Contains((description ?? string.Empty).ToLower())
С помощью С# 6.0 (который позволяет использовать функции с выражением тела и нулевого распространения) для LINQ to Objects, это можно сделать в одной строке, подобной этой (также проверяющей на null):
public static bool ContainsInsensitive(this string str, string value) => str?.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0;
IndexOf лучше всего работает в этом случае
return this
.ObjectContext
.FACILITY_ITEM
.Where(fi => fi.DESCRIPTION.IndexOf(description, StringComparison.OrdinalIgnoreCase)>=0);
Вы можете использовать string.Compare
lst.Where(x => string.Compare(x,"valueToCompare",StringComparison.InvariantCultureIgnoreCase)==0);
если вы просто хотите проверить наличие, используйте "Any"
lst.Any(x => string.Compare(x,"valueToCompare",StringComparison.InvariantCultureIgnoreCase)==0)
public static bool Contains(this string input, string findMe, StringComparison comparisonType)
{
return String.IsNullOrWhiteSpace(input) ? false : input.IndexOf(findMe, comparisonType) > -1;
}
Используйте метод 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)
);
}
StringComparison.InvariantCultureIgnoreCase просто сделайте эту работу за меня:
.Where(fi => fi.DESCRIPTION.Contains(description, StringComparison.InvariantCultureIgnoreCase));
Используйте Метод String.Equals
public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
return this.ObjectContext.FACILITY_ITEM
.Where(fi => fi.DESCRIPTION
.Equals(description, StringComparison.OrdinalIgnoreCase));
}