使用 LinqKit 在 C# 中构建表达式

Building expressions in c# with LinqKit

如果提供了查询参数

,有没有办法忽略初始 true 表达式
var query = ctx.Articles
                    .AsNoTracking()
                    .WithSmallIncludes();

Expression<Func<DbContext.Article, bool>> searchCondition = m => true;

if (!string.IsNullOrWhiteSpace(request.Title))
    searchCondition = searchCondition.Or(m => m.Title.Contains(request.Title));


if (!string.IsNullOrWhiteSpace(request.Summary))
     searchCondition = searchCondition.Or(m => m.Summary.Contains(request.Summary));

 query = query.AsExpandable().Where(searchCondition);

现在它总是 return 处理所有内容,因为表达式等于 true OR something OR Something。

如果我将初始表达式更改为 false,那么它永远不会 return 任何数据。

If i change initial expression to false, then it will never return any data.

只有当没有任何内容符合您的搜索条件,或者没有提供搜索条件时,才会出现这种情况。如果没有任何内容符合条件,那么这在技术上是正确的行为(或者其他地方有 bug/bad 数据)。因此,如果未提供搜索,您需要关注的是不应用标准。例如:

var query = ctx.Articles
                    .AsNoTracking()
                    .WithSmallIncludes();

if(string.IsNullOrWhiteSpace(request.Title) && string.IsNullOrWhiteSpace(request.Summary))
    return query;

Expression<Func<DbContext.Article, bool>> searchCondition = m => false;

if (!string.IsNullOrWhiteSpace(request.Title))
    searchCondition = searchCondition.Or(m => m.Title.Contains(request.Title));


if (!string.IsNullOrWhiteSpace(request.Summary))
     searchCondition = searchCondition.Or(m => m.Summary.Contains(request.Summary));

 query = query.AsExpandable().Where(searchCondition);

我个人可能会专注于创建一个条件列表,并在最后检查是否有任何条件,如果有则只将它们聚合到一个表达式中。如果您将来最终添加更多可搜索的组件,那将不太容易出错。

您可以将 searchCondition 设置为 null 并跳过第一个 Or 表达式。

Expression<Func<DbContext.Article, bool>> searchCondition = null;
Expression<Func<DbContext.Article, bool>> filterCondition = null;

if (!string.IsNullOrWhiteSpace(request.Title))
{
    searchCondition = m => m.Title.Contains(request.Title);
}

if (!string.IsNullOrWhiteSpace(request.Summary))
{
     filterCondition = m => m.Summary.Contains(request.Summary);
     if(searchCondition == null) 
        searchCondition  = filterCondition;
     else   
        searchCondition = searchCondition.Or(filterCondition);
}

if(searchCondition != null)
   query = query.AsExpandable().Where(searchCondition);