0

Is there a way to to ignore initial true expression, if parameters for query are supplied

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);

Right now it's always returning everything, cause expression equals to true OR something OR Something.

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

Robert
  • 3,353
  • 4
  • 32
  • 50

2 Answers2

1

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

That should only be the case if nothing matches your search criteria, or if no search criteria is provided. If nothing matches the criteria, then this is technically correct behavior (or there's a bug/bad data somewhere else). So what you need to focus on is not applying the criteria if no search is provided. For example:

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);

I'd personally probably focus on creating a list of criteria, and just check at the end to see if there are any criteria, and only aggregate them into an expression if there are some. That would be less error-prone if you end up adding more searchable components in the future.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
1

You can set searchCondition to null and skip the first Or expression.

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);
Aducci
  • 26,101
  • 8
  • 63
  • 67