Entity Framework Search Like or Equal
Using reflection (and other non SQL translatable) calls inside the query expression tree is not a good idea. In EF Core 1x and 2.x it will cause client evaluation, and EF Core v3+ will throw exception similar to EF 6.
LINQ to Entities best work with expressions. And once you need expression, you'd better make your custom extension method receive lambda expression directly rather than PropertyInfo
obtained via lambda expression as in the linked topic.
Here is a sample implementation of the above:
public static partial class QueryableExtensions{ public static IQueryable<T> WhereMatch<T>(this IQueryable<T> source, Expression<Func<T, string>> expr, string searchValue) { if (string.IsNullOrEmpty(searchValue)) return source; else if (searchValue.Contains("%")) return source.Where(expr.Map(value => EF.Functions.Like(value, searchValue))); else return source.Where(expr.Map(value => value == searchValue)); } static Expression<Func<TSource, TTarget>> Map<TSource, TIntermediate, TTarget>(this Expression<Func<TSource, TIntermediate>> source, Expression<Func<TIntermediate, TTarget>> target) => Expression.Lambda<Func<TSource, TTarget>>(Expression.Invoke(target, source.Body), source.Parameters);}
The main method is WhereMatch
. It uses a small Expression
helper method called Map
for composing lambda expressions from other lambda expressions.
Sample usage would be:
// SearchPerson searchPerson// DbContext dbvar query = db.Set<Person>() .WhereMatch(p => p.Name, searchPerson.Name) .WhereMatch(p => p.MothersName, searchPerson.MothersName) .WhereMatch(p => p.FathersName, searchPerson.FathersName);
For Equality comparison you should use ==
:
EFPersonObject.Where(m => m.Name == searchPerson.Name);
For LIKE
:
like 'something%'
: (StartsWith
Method)
EFPersonObject.Where(m => m.Name.StartsWith(searchPerson.Name));
like '%something'
: (EndsWith
Method)
EFPersonObject.Where(m => m.Name.EndsWith(searchPerson.Name));
like '%something%'
: (Contains
Method)
EFPersonObject.Where(m => m.Name.Contains(searchPerson.Name));