Как динамически добавлять оператор OR в предложение WHERE в LINQ

У меня есть массив строк с переменным размером, и я пытаюсь запрограммировать цикл через массив и сопоставлять все строки в таблице, где столбец «Метки» содержит хотя бы одну из строк в массиве. Вот несколько псевдокодов:

IQueryable allSongMatches = musicDb.Songs; // all rows in the table 

Я могу легко запросить эту фильтрацию таблицы на фиксированном наборе строк, например:

  allSongMatches=allSongMatches.Where(SongsVar => SongsVar.Tags.Contains("foo1") || SongsVar.Tags.Contains("foo2") || SongsVar.Tags.Contains("foo3")); 

Однако это не работает (я получаю следующую ошибку: «Лямбда-выражение с телом оператора не может быть преобразовано в дерево выражений»)

  allSongMatches = allSongMatches.Where(SongsVar => { bool retVal = false; foreach(string str in strArray) { retVal = retVal || SongsVar.Tags.Contains(str); } return retVal; }); 

Может ли кто-нибудь показать мне правильную страtagsю для этого? Я все еще новичок в мире LINQ 🙂

Вы можете использовать class PredicateBuilder :

 var searchPredicate = PredicateBuilder.False(); foreach(string str in strArray) { var closureVariable = str; // See the link below for the reason searchPredicate = searchPredicate.Or(SongsVar => SongsVar.Tags.Contains(closureVariable)); } var allSongMatches = db.Songs.Where(searchPredicate); 

LinqToSql странное поведение

Недавно я создал метод расширения для создания поиска строк, который также позволяет выполнять поиск OR . О блоге

Я также создал его как пакет nuget, который вы можете установить:

http://www.nuget.org/packages/NinjaNye.SearchExtensions/

После установки вы сможете сделать следующее

 var result = db.Songs.Search(s => s.Tags, strArray); 

Если вы хотите создать свою собственную версию, чтобы разрешить вышеуказанное, вам нужно будет сделать следующее:

 public static class QueryableExtensions { public static IQueryable Search(this IQueryable source, Expression> stringProperty, params string[] searchTerms) { if (!searchTerms.Any()) { return source; } Expression orExpression = null; foreach (var searchTerm in searchTerms) { //Create expression to represent x.[property].Contains(searchTerm) var searchTermExpression = Expression.Constant(searchTerm); var containsExpression = BuildContainsExpression(stringProperty, searchTermExpression); orExpression = BuildOrExpression(orExpression, containsExpression); } var completeExpression = Expression.Lambda>(orExpression, stringProperty.Parameters); return source.Where(completeExpression); } private static Expression BuildOrExpression(Expression existingExpression, Expression expressionToAdd) { if (existingExpression == null) { return expressionToAdd; } //Build 'OR' expression for each property return Expression.OrElse(existingExpression, expressionToAdd); } } 

Кроме того, взгляните на проект github для NinjaNye.SearchExtensions как у этого есть другие варианты, и он был частично реорганизован, чтобы разрешить другие комбинации

Либо создайте Expression самостоятельно, либо посмотрите на другой маршрут.

Предполагая, что possibleTags представляет собой набор тегов, вы можете использовать закрытие и соединение, чтобы найти совпадения. Это должно найти любые песни с хотя бы одним тегом в возможныхTags:

 allSongMatches = allSongMatches.Where(s => (select t from s.Tags join tt from possibleTags on t == tt select t).Count() > 0) 

Есть другой, несколько более простой метод, который это выполнит. Блог ScottGu описывает динамическую библиотеку linq, которую я нашел очень полезной в прошлом. По существу, он генерирует запрос из строки, в которую вы проходите. Вот пример кода, который вы должны написать:

 Dim Northwind As New NorthwindDataContext Dim query = Northwind.Products _ .Where("CategoryID=2 AND UnitPrice>3") _ .OrderBy("SupplierId") Gridview1.DataSource = query Gridview1.DataBind() 

Более подробную информацию можно найти в блоге scottgu .

  • Доступ к свойствам через параметр Generic type
  • LINQ-to-SQL и хранимые процедуры?
  • «CompanyName.Foo» - это «пространство имен», но используется как «тип»,
  • Linq: добавление условий к условию where условно
  • Несколько / одиночный экземпляр Linq to SQL DataContext
  • Как выполнить объединение в linq в sql с синтаксисом метода?
  • C # Linq to SQL: Как выразить «CONVERT ( AS INT)»?
  • Entity Framework / Linq to SQL: Skip & Take
  • Макс или по умолчанию?
  • Как сравнивать только даты без времени в типах DateTime в Linq to SQL с Entity Framework?
  • C # LINQ to SQL: рефакторинг этого общего метода GetByID
  • Давайте будем гением компьютера.