为动态关键字构建动态 where 子句或使用 IQueryable C# Linq
Building a dynamic where clause for dynamic keywords or using IQueryable C# Linq
我正在尝试使用 LINQ 编写动态 where 子句,以返回包含字符串数组中提供的任何关键字的所有行。到目前为止,结果并没有像我预期的那样返回,查看 SQL 我可以看到问题所在。
IQueryable<comments> query = _db.comments;
if (score != null)
query = query.Where(x => x.score == score);
if (dateFrom != null)3
query = query.Where(x => x.date_created >= dateFrom);
if (dateTo != null)
query = query.Where(x => x.date_created <= dateTo);
if (keywords != null)
{
//how to use OR for each in array?
foreach (var keyword in keywords)
{
var keywordCondition = keyword;
query = query.Where(x => x.text.Contains(keywordCondition));
}
}
WHERE ([Extent1].[score] = @p__linq__0)
AND ([Extent1].[date_created] >= @p__linq__1)
AND ([Extent1].[date_created] <= @p__linq__2)
AND ([Extent1].[text] LIKE @p__linq__3 ESCAPE '~')
AND ([Extent1].[text] LIKE @p__linq__4 ESCAPE '~')
--应该是
WHERE ([Extent1].[score] = @p__linq__0)
AND ([Extent1].[date_created] >= @p__linq__1)
AND ([Extent1].[date_created] <= @p__linq__2)
AND (([Extent1].[text] LIKE @p__linq__3 ESCAPE '~')
OR ([Extent1].[text] LIKE @p__linq__4 ESCAPE '~'))
我已经花了几个小时寻找解决方案,希望有人能帮助我。
提前致谢
如您所料,这是您需要更改的问题部分,因为它将 "AND" 所有子句。
//how to use OR for each in array?
foreach (var keyword in keywords)
{
var keywordCondition = keyword;
query = query.Where(x => x.text.Contains(keywordCondition));
}
我认为您可以将其更改为:
query = query.Where(x => keywords.Any(kw => x.text.Contains(kw));
您真的应该研究动态 LINQ 查询(这里解释得很好 - http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library)
您可以像下面这样指定您的查询 -
.Where("Column1 = value1 OR Column2 = value2");
不知道有没有更干净的方法,改一下
foreach (var keyword in keywords)
{
var keywordCondition = keyword;
query = query.Where(x => x.text.Contains(keywordCondition));
}
到
query = query.Where(x => keywords.Any(k => x.text.Contains(k));
如果 x.text
包含列表 中的任何关键字,Any()
将 return 一个布尔值
如果您尝试动态构建谓词(条件),我发现最简单、最灵活的方法是使用 PredicateBuilder。
http://www.albahari.com/nutshell/predicatebuilder.aspx
它使您可以完全控制是使用 and
还是 or
来构建查询。
我正在尝试使用 LINQ 编写动态 where 子句,以返回包含字符串数组中提供的任何关键字的所有行。到目前为止,结果并没有像我预期的那样返回,查看 SQL 我可以看到问题所在。
IQueryable<comments> query = _db.comments;
if (score != null)
query = query.Where(x => x.score == score);
if (dateFrom != null)3
query = query.Where(x => x.date_created >= dateFrom);
if (dateTo != null)
query = query.Where(x => x.date_created <= dateTo);
if (keywords != null)
{
//how to use OR for each in array?
foreach (var keyword in keywords)
{
var keywordCondition = keyword;
query = query.Where(x => x.text.Contains(keywordCondition));
}
}
WHERE ([Extent1].[score] = @p__linq__0)
AND ([Extent1].[date_created] >= @p__linq__1)
AND ([Extent1].[date_created] <= @p__linq__2)
AND ([Extent1].[text] LIKE @p__linq__3 ESCAPE '~')
AND ([Extent1].[text] LIKE @p__linq__4 ESCAPE '~')
--应该是
WHERE ([Extent1].[score] = @p__linq__0)
AND ([Extent1].[date_created] >= @p__linq__1)
AND ([Extent1].[date_created] <= @p__linq__2)
AND (([Extent1].[text] LIKE @p__linq__3 ESCAPE '~')
OR ([Extent1].[text] LIKE @p__linq__4 ESCAPE '~'))
我已经花了几个小时寻找解决方案,希望有人能帮助我。
提前致谢
如您所料,这是您需要更改的问题部分,因为它将 "AND" 所有子句。
//how to use OR for each in array?
foreach (var keyword in keywords)
{
var keywordCondition = keyword;
query = query.Where(x => x.text.Contains(keywordCondition));
}
我认为您可以将其更改为:
query = query.Where(x => keywords.Any(kw => x.text.Contains(kw));
您真的应该研究动态 LINQ 查询(这里解释得很好 - http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library)
您可以像下面这样指定您的查询 -
.Where("Column1 = value1 OR Column2 = value2");
不知道有没有更干净的方法,改一下
foreach (var keyword in keywords)
{
var keywordCondition = keyword;
query = query.Where(x => x.text.Contains(keywordCondition));
}
到
query = query.Where(x => keywords.Any(k => x.text.Contains(k));
如果 x.text
包含列表 中的任何关键字,Any()
将 return 一个布尔值
如果您尝试动态构建谓词(条件),我发现最简单、最灵活的方法是使用 PredicateBuilder。
http://www.albahari.com/nutshell/predicatebuilder.aspx
它使您可以完全控制是使用 and
还是 or
来构建查询。