最简单的方法
Just use
if (comparison == ComparisonType.StartsWith)
query = query.Where(e => e.StringProperty.StartsWith("SearchString"));
else if ...
艰难的路
如果您想做这样的事情,要么确保您的 LINQ 提供程序能够以某种方式知道这个新方法,以及它如何转换为 SQL(不太可能),要么阻止您的方法到达 LINQ 提供程序,并向提供程序提供一些东西它理解(很难)。例如,代替
query.Where(e => CompMethod(e.StringProperty, "SearchString", comparsionType))
你可以创建类似的东西
var query = source.WhereLike(e => e.StringProperty, "SearchString", comparsionType)
用下面的代码
public enum ComparisonType { StartsWith, EndsWith, Contains }
public static class QueryableExtensions
{
public static IQueryable<T> WhereLike<T>(
this IQueryable<T> source,
Expression<Func<T, string>> field,
string value,
SelectedComparisonType comparisonType)
{
ParameterExpression p = field.Parameters[0];
return source.Where(
Expression.Lambda<Func<T, bool>>(
Expression.Call(
field.Body,
comparisonType.ToString(),
null,
Expression.Constant(value)),
p));
}
}
您甚至可以通过这种方式添加其他条件
var query = from e in source.WhereLike(
e => e.StringProperty, "SearchString", comparsionType)
where e.OtherProperty == 123
orderby e.StringProperty
select e;
非常非常艰难的路
(从技术上讲)可以在提供者看到表达式树之前重写它,因此您can使用您首先想到的查询,但您必须
- 创建一个
Where(this IQueryable<EntityType> source, Expression<Func<EntityType, bool>> predicate)
拦截Queryable.Where
,
- 重写表达式树,替换你的
CompMethod
,无论它在哪里,与其中之一String
方法,
- 调用原来的
Queryable.Where
用重写的表达式,
- 首先,能够首先遵循上面的扩展方法!
但这对于您的想法来说可能太复杂了。