我尝试创建用于过滤数据库中不同实体通用方法,以避免为每个实体创建庞大的方法,并使用非常相似的if语句组合过滤规则。
现在,我试图创建一个表达式,它表示相等比较,作为参数表达式,描述要比较的属性和一些值。
我的概念如何解决问题,我创建的基础上,其他职位显示下面的代码片段:
public class FuelCard
{
public int Id { get; set; }
public string Number { get; set; }
public virtual User User { get; set; }
}
public static IQueryable<TEntity> ApplyFilter<TEntity, TProperty>(
this IQueryable<TEntity> query,
Expression<Func<TEntity, TProperty>> expr, TProperty value)
{
Expression<Func<TEntity, bool>> predicate = param => true;
var filterExpression = Expression.Equal(expr, Expression.Constant(value));
var lambda = Expression.Lambda<Func<TEntity, bool>>(filterExpression);
predicate = predicate.And(lambda);
return query.Where(predicate);
}
最后我想这样使用它:
IQueryable<FuelCard> query = // Get cards from database as IQueryable
query = query.ApplyFilter(x => x.Id, 85);
query = query.ApplyFilter(x => x.User.LastName + " " + x.User.FirstName, "Jon Green");
我想定义一个匿名表达式,描述如何获取列的值,然后应用不同的过滤器(这里显示了一个简单的例子与平等的方法)。
但是当我调用Expression.Equal时,我得到了一个错误,即Func和Int32没有二元运算符。
在所有示例中,都创建了具有属性名称的Expression.Parameter对象,但它们仅对实体类中的属性进行操作(不使用导航属性等)。但是否可以将过滤器表达式与命名属性表达式组合?
我希望我能清楚地描述我试图达到的目标,以及与标准示例的区别,这是我的问题的根源
我将非常感激,如果有人帮助我如何创建这样的过滤器,以便比较表达式的结果在给定的参数与值,然后应用 predicate 到查询,以便运行它对sql数据库:)
3条答案
按热度按时间krcsximq1#
它是这样的:
使用方法如下:
一般来说,多个
.Where()
都隐含在&&
中(在 * 和 * 之间),所以你只需要创建一个基于属性选择器表达式加上等于加上传递的值的表达式,然后返回一个使用该表达式的.Where()
。xxls0lw82#
Xanatos已经完全回答了你的问题,但是我只是想演示一些其他的方法来概括你的数据库表和查询语句。第一种是使用函数+接口来代替lambda:
另一种方法是泛型单例或泛型静态函数,它们确实倾向于与Linq -〉SQL一起工作,并且通常以更可读的方式结束
这是十分粗糙而不冉然的但却表明了基本的概念:
3df52oht3#
这听起来和我解决的一个问题非常相似。在我的例子中,我必须根据用Sql语法定义的复杂过滤器将对象过滤到不同的类别中。
我已经创建了一个Nuget包
DynamicFilter.Sql
来从Sql动态生成lambda表达式。以下是一个示例
该软件包是开源的,可在github上获得。