Цей код враховує регістри, як зробити його нечутливим?
public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
return this.ObjectContext.FACILITY_ITEM.Where(fi => fi.DESCRIPTION.Contains(description));
}
Цей код враховує регістри, як зробити його нечутливим?
public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
return this.ObjectContext.FACILITY_ITEM.Where(fi => fi.DESCRIPTION.Contains(description));
}
Відповіді:
Припустимо, що ми тут працюємо зі струнами, ось ще одне "елегантне" рішення IndexOf()
.
public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
return this.ObjectContext.FACILITY_ITEM
.Where(fi => fi.DESCRIPTION
.IndexOf(description, StringComparison.OrdinalIgnoreCase) != -1);
}
fi => fi.DESCRIPTION.ToLower().Contains(description.ToLower())
IEqualityComparer<string>
атрибут для обробки того, як буде працювати порівняння. Використовуйте ToLower і ToUpper для перевірки рівності - це погана ідея. Спробуйте: .Contains(description, StringComparer.CurrentCultureIgnoreCase)
наприклад
Error 1 'string' does not contain a definition for 'Contains' and the best extension method overload 'System.Linq.ParallelEnumerable.Contains<TSource>(System.Linq.ParallelQuery<TSource>, TSource, System.Collections.Generic.IEqualityComparer<TSource>)' has some invalid arguments
Contains
з StringComparer
не отримує рядок як параметр, тому це буде помилка збирання. IndexOf
на , Queryable
ймовірно , не може бути переведена на SQL. Особисто я вважав цю відповідь цілком справедливою, коли ми говоримо про LINQ до бази даних.
Якщо запит LINQ виконується в контексті бази даних, виклик до Contains()
цього картографується LIKE
оператору:
.Where(a => a.Field.Contains("hello"))
стає Field LIKE '%hello%'
. LIKE
Оператор чутливий до регістру за замовчуванням, але може бути змінений шляхом зміни параметрів сортування стовпця .
Якщо запит LINQ виконується в контексті .NET, ви можете використовувати IndexOf () , але цей метод не підтримується в LINQ в SQL.
LINQ до SQL не підтримує методи, які приймають CultureInfo як параметр, ймовірно, тому, що він не може гарантувати, що сервер SQL обробляє культури так само, як .NET. Це не зовсім вірно, тому що це підтримує StartsWith(string, StringComparison)
.
Однак, схоже, він не підтримує метод, який оцінюється LIKE
в LINQ до SQL, і порівняння нечутливого до регістру в .NET, що робить неможливим послідовно робити нечутливі до регістру Contains ().
insensitive
пошук випадків , а в іншому мені це потрібно case sensitive
. Мені просто потрібно виконати ступінь продуктивності та використовувати "toLower ()"?
Тут прийнята відповідь не згадує факту, що якщо у вас є нульовий рядок, ToLower () викине виняток. Більш безпечним способом було б зробити:
fi => (fi.DESCRIPTION ?? string.Empty).ToLower().Contains((description ?? string.Empty).ToLower())
Використовуючи C # 6.0 (що дозволяє виконувати функції експресії та нульове поширення), для LINQ до об'єктів це можна зробити в одному рядку, як це (також перевіряючи на 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);
якщо ви просто хочете перевірити, чи містить, тоді використовуйте "Будь-який"
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;
}
StringComppare.InvariantCultureIgnoreCase просто зробіть для мене роботу:
.Where(fi => fi.DESCRIPTION.Contains(description, StringComparison.InvariantCultureIgnoreCase));
Чесно кажучи, це не повинно бути складним. Може здатися, що на початку, але це не так. Ось простий запит linq в C #, який виконує саме так, як вимагали.
У своєму прикладі я працюю проти списку осіб, які мають одне властивість під назвою FirstName.
var results = ClientsRepository().Where(c => c.FirstName.ToLower().Contains(searchText.ToLower())).ToList();
Це дозволить здійснити пошук у базі даних за допомогою малих записів, але поверне повні результати.
Використовуйте метод String.Equals
public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description)
{
return this.ObjectContext.FACILITY_ITEM
.Where(fi => fi.DESCRIPTION
.Equals(description, StringComparison.OrdinalIgnoreCase));
}