C#将表达式作为参数传递并使用PredicateBuilder
我想使用一个“criteria”对象动态构建LinqToSQL和EntityFramework查询子句,如果需要的话,还可以在一个简单的PredicateBuilder()中利用C# 我只是想说清楚——我不知道如何创建C#表达式;o) 筛选器运算符和值定义为我的“查询条件”类的属性,如下所示:C#将表达式作为参数传递并使用PredicateBuilder,c#,entity-framework,linq,linq-to-sql,predicatebuilder,C#,Entity Framework,Linq,Linq To Sql,Predicatebuilder,我想使用一个“criteria”对象动态构建LinqToSQL和EntityFramework查询子句,如果需要的话,还可以在一个简单的PredicateBuilder()中利用C# 我只是想说清楚——我不知道如何创建C#表达式;o) 筛选器运算符和值定义为我的“查询条件”类的属性,如下所示: public class QueryCriteria { public DateTimeFilter DateTimeCompleted { get; set; } } “过滤器”定义为: pu
public class QueryCriteria
{
public DateTimeFilter DateTimeCompleted { get; set; }
}
“过滤器”定义为:
public class DateTimeFilter
{
public FilterOperator FilterOperator { get; set; }
public DateTime FilterToken { get; set; }
}
“过滤器操作符”是一个普通的C#enum:
我希望使用以下方法在我的存储库中动态构建LinqToSQL和EntityFramework查询:
if (criteria.DateTimeCompleted != null)
{
var predicate = PredicateBuilder.True(query);
switch (criteria.DateTimeCompleted.FilterOperator)
{
case FilterOperator.ExactMatch:
predicate = predicate.And(p => string.Equals(p.DateTimeCompleted.Value, criteria.DateTimeCompleted.FilterToken));
break;
case FilterOperator.GreaterThan:
predicate = predicate.And(p => p.DateTimeCompleted.Value > criteria.DateTimeCompleted.FilterToken);
break;
case FilterOperator.GreaterThanOrEqualTo:
predicate = predicate.And(p => p.DateTimeCompleted.Value >= criteria.DateTimeCompleted.FilterToken);
break;
case FilterOperator.LessThan:
predicate = predicate.And(p => p.DateTimeCompleted.Value < criteria.DateTimeCompleted.FilterToken);
break;
case FilterOperator.LessThanOrEqualTo:
predicate = predicate.And(p => p.DateTimeCompleted.Value <= criteria.DateTimeCompleted.FilterToken);
break;
default:
throw new InvalidOperationException("Can't use the specified filter operator on a DateTime.");
}
query = query.Where(predicate);
}
这可能吗?如果可能的话,如何实现?这肯定是可能的(而且不需要PredicateBuilder)。您只需将支持的过滤器操作符
映射到相应的表达式
下面是一个自定义扩展方法,它可以:
public static class QueryableExtensions
{
public static IQueryable<T> Where<T>(this IQueryable<T> source, DateTimeFilter filter, Expression<Func<T, DateTime>> target)
{
if (filter == null) return source;
var left = target.Body;
var right = Expression.Constant(filter.FilterToken);
Expression condition;
switch (filter.FilterOperator)
{
case FilterOperator.ExactMatch:
condition = Expression.Equal(left, right);
break;
case FilterOperator.GreaterThan:
condition = Expression.GreaterThan(left, right);
break;
case FilterOperator.GreaterThanOrEqualTo:
condition = Expression.GreaterThanOrEqual(left, right);
break;
case FilterOperator.LessThan:
condition = Expression.LessThan(left, right);
break;
case FilterOperator.LessThanOrEqualTo:
condition = Expression.LessThanOrEqual(left, right);
break;
default:
throw new InvalidOperationException("Can't use the specified filter operator on a DateTime.");
}
var predicate = Expression.Lambda<Func<T, bool>>(condition, target.Parameters);
return source.Where(predicate);
}
}
query = query.Where(criteria.DateTimeCompleted.GetPredicate(query, p => p.DateTimeCompleted.Value));
public static class QueryableExtensions
{
public static IQueryable<T> Where<T>(this IQueryable<T> source, DateTimeFilter filter, Expression<Func<T, DateTime>> target)
{
if (filter == null) return source;
var left = target.Body;
var right = Expression.Constant(filter.FilterToken);
Expression condition;
switch (filter.FilterOperator)
{
case FilterOperator.ExactMatch:
condition = Expression.Equal(left, right);
break;
case FilterOperator.GreaterThan:
condition = Expression.GreaterThan(left, right);
break;
case FilterOperator.GreaterThanOrEqualTo:
condition = Expression.GreaterThanOrEqual(left, right);
break;
case FilterOperator.LessThan:
condition = Expression.LessThan(left, right);
break;
case FilterOperator.LessThanOrEqualTo:
condition = Expression.LessThanOrEqual(left, right);
break;
default:
throw new InvalidOperationException("Can't use the specified filter operator on a DateTime.");
}
var predicate = Expression.Lambda<Func<T, bool>>(condition, target.Parameters);
return source.Where(predicate);
}
}
query = query.Where(criteria.DateTimeCompleted, p => p.DateTimeCompleted.Value);