如何在LINQ中动态添加OR运算符到WHERE子句

29 linq dynamic linq-to-sql

我有一个可变大小的字符串数组,我正在尝试以编程方式循环遍历数组并匹配表中的所有行,其中"Tags"列包含数组中的至少一个字符串.这是一些伪代码:

 IQueryable<Songs> allSongMatches = musicDb.Songs; // all rows in the table
Run Code Online (Sandbox Code Playgroud)

我可以轻松地在一组固定的字符串上查询此表过滤,如下所示:

 allSongMatches=allSongMatches.Where(SongsVar => SongsVar.Tags.Contains("foo1") || SongsVar.Tags.Contains("foo2") || SongsVar.Tags.Contains("foo3"));
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用(我得到以下错误:"带有语句体的lambda表达式无法转换为表达式树")

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

有人能告诉我完成这个的正确策略吗?我仍然是LINQ世界的新手:-)

Meh*_*ari 33

你可以使用这个PredicateBuilder类:

var searchPredicate = PredicateBuilder.False<Songs>();

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);
Run Code Online (Sandbox Code Playgroud)

LinqToSql奇怪的行为

  • 它必须是假的,因为构造的查询需要看起来像“假 || 包含 x || 包含 y || ...” (2认同)