I am using LinqKit's predicate builder expressions for search functions. I build a dynamic expression which is then applied on the entity.
Had this working before, but after migrating to .net core 3.1, I am getting errors due to the restriction on client side valuations.
I understand this can be overcome by forcing AsEnumerable() casting.
However I don't understand exactly how to do this on predicate expressions.
Predicate builder function:
private Expression<Func<A, bool>> BuildDynamicWhereClauseForA(string searchValue)
{
var predicate = PredicateBuilder.New<A>(true);
if (!string.IsNullOrWhiteSpace(searchValue))
{
var searchTerms = searchValue.Split(' ').ToList().ConvertAll(x => x.ToLower());
foreach (var item in searchTerms)
{
predicate = predicate.Or(x => x.col1.ToLower().Contains(item));
predicate = predicate.Or(x => x.col2.ToLower().Contains(item));
predicate = predicate.Or(x => x.col3.ToString().ToLower().Contains(item));
}
}
return predicate;
}
Function which performs actual database call:
private List<AD> GetDataFromDBForA(string searchBy ...)
{
var whereClause = BuildDynamicWhereClauseForA(searchBy);
List<AD> result;
result = db.A.AsExpandable()
.Where(whereClause)
.OrderBy(sortBy)
.Select(m => new AD
{
...
...
})
.Skip(skip)
.Take(take)
.ToList()
return result;
}
This is the error I get:
> The LINQ expression 'DbSet<A>
> .Where(e => e.col1.ToLower().Contains(__item_0) || e.col2.ToLower().Contains(__item_0) ||
> e.Col3.ToString().ToLower().Contains(__item_0))' could not be
> translated. Either rewrite the query in a form that can be translated,
> or switch to client evaluation explicitly by inserting a call to
> either AsEnumerable(), AsAsyncEnumerable(), ToList(), or
> ToListAsync().
I understand why this is happening.
But I don't understand predicates as well and can't seem to cast the result to enumerable or list to force client side evaluation.
What I have tried:
result = db.A.AsEnumerable()
.AsQueryable()
.Where(whereClause)
.OrderBy(sortBy)