如何将额外的参数添加到表达式<;Func<;T、 bool>>;泛型存储库中的谓词

本文关键字:gt lt bool 泛型 存储 谓词 Func 添加 参数 表达式 | 更新日期: 2023-09-27 18:29:44

我使用的是通用存储库,需要在其中一个存储库方法中添加额外的参数。例如,我在数据库中有isDeleted列,我想将该列作为false添加到谓词中。如何从存储库方法向谓词添加额外的参数?此额外参数对于所有表都是固定的。(isDeleted=false)

这是我最初的方法,从数据库中获取单个记录。

public T GetSingle(Expression<Func<T, bool>> expression)
{
    return _dbSet.Where(expression).SingleOrDefault();
}

这是一个更新的版本,添加了我迄今为止使用的额外参数。

public T GetSingle(Expression<Func<T, bool>> expression)
{
    Expression<Func<T, bool>> extra = d => d.GetType().GetProperty("isDeleted").Equals(false);
    var exp = Expression.And(expression.Body, extra.Body);
    var body = Expression.And(expression.Body, extra.Body);
    var lambda = Expression.Lambda<Func<T, bool>>(body, extra.Parameters);
    return _dbSet.Where(lambda).SingleOrDefault();
}

但这个更新的版本提供了这样的lambda主体,当然它不起作用。

((d.ID == value(ProjectName.Namespace.Controllers.ControllerName).User.CompanyId) And d.GetType().GetProperty("isDeleted").Equals(Convert(False)))

如何将额外的参数添加到表达式<;Func<;T、 bool>>;泛型存储库中的谓词

public T GetSingle<T>(Expression<Func<T, bool>> expression)
{
    var @params = expression.Parameters;
    var checkNotDeleted = Expression.Equal(Expression.PropertyOrField(@params[0], "isDeleted"), Expression.Constant(false));
    var originalBody = expression.Body;
    var fullExpr = Expression.And(originalBody, checkNotDeleted);
    var lambda = Expression.Lambda<Func<T, bool>>(fullExpr, @params);
    return _dbSet.Where(lambda).SingleOrDefault();
}

一旦开始使用Expression的方法,就需要始终使用它们(当然,Expression.Constant除外)。您编写的所有逻辑和代码都必须用Expression节点表示。

有一个方法PropertyOrField,它从一个特定的表达式中读取一个属性的值。在这种情况下,我们从参数中读取它(即d => d.isDeleted-我们正在编写d.isDeleted部分)。然后我们需要将该值与false进行比较。

最后,我们简单地将原始表达式And转换为我们的表达式,并使用原始参数创建一个lambda。

查看PredicateBuilder,特别是"Generic Predicates"部分,该部分解释了如何创建通用约束来过滤项目

您可以有一个包含IsDeleted属性的BaseEntity

所有其他实体都应该是该BaseEntity的子实体。

现在在存储库中,

public class Repository<T> where T : BaseEntity
{
....
}

在查询中,您还可以为IsDeleted添加表达式。

请看这里:通用存储库模式-实体框架、ASP.NET MVC和单元测试三角形

您可以将方法更改为:

public T GetSingle(param Expression<Func<T, bool>>[] expression)

使用数组和关键字param

然后您可以发送两个、三个、四个或任意数量的参数。