У меня есть один большой вопрос.
Я получил запрос linq, чтобы выразить это просто так:
from xx in table
where xx.uid.ToString().Contains(string[])
select xx
Значения string[]
массива будут числами вроде (1,45,20,10 и т. Д.)
По умолчанию .Contains
используется .Contains(string)
.
Мне нужно это сделать вместо этого: .Contains(string[])
...
EDIT: один пользователь предложил написать класс расширения для string[]
. Я хотел бы узнать, как это сделать, но кто-нибудь хочет указать мне в правильном направлении?
РЕДАКТИРОВАТЬ: uid также будет числом. Вот почему он конвертируется в строку.
Кому-нибудь помочь?
Ответы:
spoulson есть это почти верно, но вам нужно создать
List<string>
изstring[]
первых. На самом делеList<int>
было бы лучше , если UID такжеint
.List<T>
поддерживаетContains()
. Этоuid.ToString().Contains(string[])
будет означать, что uid в виде строки содержит все значения массива в виде подстроки ??? Даже если бы вы написали метод расширения, смысл этого был бы неправильным.[РЕДАКТИРОВАТЬ]
Если вы не изменили его и не написали,
string[]
как демонстрирует Митч Уит, вы просто сможете пропустить этап преобразования.[ENDEDIT]
Вот что вы хотите, если вы не используете метод расширения (если у вас еще нет коллекции потенциальных uid в виде целых чисел - просто используйте
List<int>()
вместо этого). При этом используется синтаксис цепочечного метода, который, на мой взгляд, более понятный, и выполняется преобразование в int, чтобы запрос можно было использовать с большим количеством поставщиков.источник
List<int>
вместо этого создать коллекцию в памяти как и пропуститьToString
вызов.Если вы действительно хотите реплицировать Contains , но для массива, вот метод расширения и пример кода для использования:
источник
!string.IsNullOrEmpty(str)
проверка прошла успешно, в результате чегоvalues.Length > 0
условие игнорировалось, но длина Values была равна 0 , тогда он перешел бы в,foreach
а затем немедленно прервался бы, потому что в массиве нет записей, переходя непосредственно вreturn false
.Попробуйте следующее.
источник
LINQ в .NET 4.0 предлагает вам еще один вариант; метод .Any ();
источник
Any()
иAll()
методы настолько просты :) Я могу использоватьt => words.All(w => t.Title.Contains(w))
.Или, если у вас уже есть данные в списке и вы предпочитаете другой формат Linq :)
источник
Как насчет:
источник
Это пример одного из способов написания метода расширения (примечание: я бы не стал использовать его для очень больших массивов; более подходящей была бы другая структура данных ...):
источник
Это поздний ответ, но я считаю, что он все еще полезен .
Я создал пакет nuget NinjaNye.SearchExtension , который может помочь решить эту самую проблему:
Вы также можете искать несколько строковых свойств
Или выполните команду
RankedSearch
which return,IQueryable<IRanked<T>>
которая просто включает свойство, показывающее, сколько раз появлялись условия поиска:На странице GitHub по проектам есть более подробное руководство: https://github.com/ninjanye/SearchExtensions
Надеюсь, это поможет будущим посетителям
источник
IQueryable
иIEnumerable
- только будьте в виду, что если вы подключите его к IEnumerable, он будет работать в памяти, а не создавать запрос и отправлять его источникуМетод расширения Linq. Будет работать с любым объектом IEnumerable:
Использование:
источник
Я считаю, что вы могли бы сделать что-то подобное.
источник
Итак, правильно ли я предполагаю, что uid - это уникальный идентификатор (Guid)? Это просто пример возможного сценария или вы действительно пытаетесь найти guid, который соответствует массиву строк?
Если это правда, вы можете действительно переосмыслить весь этот подход, это кажется действительно плохой идеей. Вероятно, вам стоит попытаться сопоставить Guid с Guid
Честно говоря, я не могу представить себе сценарий, при котором сопоставление массива строк с использованием "contains" с содержимым Guid было бы хорошей идеей. Во-первых, Contains () не гарантирует порядок чисел в Guid, поэтому вы потенциально можете сопоставить несколько элементов. Не говоря уже о том, чтобы сравнивать направляющие таким образом, было бы намного медленнее, чем просто делать это напрямую.
источник
Вы должны написать это наоборот, проверив, что ваш список идентификаторов привилегированных пользователей содержит идентификатор в этой строке таблицы:
LINQ ведет себя здесь довольно ярко и преобразует его в хороший оператор SQL:
который в основном включает содержимое массива search в запрос sql и выполняет фильтрацию с ключевым словом IN в SQL.
источник
Мне удалось найти решение, но не лучшее, поскольку для этого требуется использовать AsEnumerable (), который будет возвращать все результаты из БД, к счастью, у меня есть только 1k записей в таблице, поэтому это не очень заметно, но вот .
Мой исходный пост следует:
источник
Лучшее решение, которое я нашел, - это создать в SQL табличную функцию, которая дает результаты, например:
Затем вы просто перетаскиваете функцию в свой конструктор LINQ.dbml и вызываете ее так же, как и другие объекты. LINQ даже знает столбцы вашей сохраненной функции. Я называю это так:
Невероятно простой и действительно раскрывает всю мощь SQL и LINQ в приложении ... и вы, конечно же, можете сгенерировать любую функцию с табличным значением, какую захотите, для тех же эффектов!
источник
Я считаю, что вы действительно хотите: давайте представим сценарий, у вас есть две базы данных и у них есть общая таблица продуктов. И вы хотите выбрать продукты из таблицы «A», которая имеет общий идентификатор с «B».
использование метода contains было бы слишком сложно сделать это то, что мы делаем, это пересечение, и для этого есть метод, называемый пересечением
пример из msdn: http://msdn.microsoft.com/en-us/vcsharp/aa336761.aspx#intersect1
int [] числа = (0, 2, 4, 5, 6, 8, 9); int [] numbersB = (1, 3, 5, 7, 8); var = commonNumbers numbersA.Intersect (numbersB);
Я думаю то, что вам нужно, легко решается с помощью пересечения
источник
Проверьте этот метод расширения:
источник
источник
Пытаться:
источник
источник
источник
источник
источник