如何向 Expression<Func<T, bool>> Generic Repository 中的谓词添加额外参数
How to add extra parameter to Expression<Func<T, bool>> predicate in Generic Repository
我正在使用通用存储库,我需要在其中一种存储库方法中添加额外的参数。例如,我在数据库中有 isDeleted 列,我想将此列添加为假谓词。
如何从存储库方法向谓词添加额外参数?这个额外的参数对于所有表都是固定的。 (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)))
查看 PredicateBuilder,尤其是 "Generic Predicates" 部分,该部分解释了如何创建通用约束来过滤您的项目
你可以有一个 BaseEntity
其中包含 IsDeleted
属性.
所有其他实体都应该是此 BaseEntity
的子实体。
现在在存储库中,
public class Repository<T> where T : BaseEntity
{
....
}
并且在查询中,您还可以为 IsDeleted
添加表达式。
请看这里:Generic Repository Pattern - Entity Framework, ASP.NET MVC and Unit Testing Triangle
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
除外)。您编写的所有逻辑和代码都必须用表达式节点表示。
有一种方法 PropertyOrField
可以从特定表达式中读取 属性 的值。在这种情况下,我们从参数中读取它(即 d => d.isDeleted
- 我们正在编写 d.isDeleted
部分)。然后我们需要将值与 false 进行比较。
最后,我们简单地And
我们的原始表达式,并使用原始参数创建一个 lambda。
您可以将方法更改为:
public T GetSingle(param Expression<Func<T, bool>>[] expression)
使用数组,关键字param.
您可以发送两个、三个、四个或任意数量的参数。
我正在使用通用存储库,我需要在其中一种存储库方法中添加额外的参数。例如,我在数据库中有 isDeleted 列,我想将此列添加为假谓词。 如何从存储库方法向谓词添加额外参数?这个额外的参数对于所有表都是固定的。 (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)))
查看 PredicateBuilder,尤其是 "Generic Predicates" 部分,该部分解释了如何创建通用约束来过滤您的项目
你可以有一个 BaseEntity
其中包含 IsDeleted
属性.
所有其他实体都应该是此 BaseEntity
的子实体。
现在在存储库中,
public class Repository<T> where T : BaseEntity
{
....
}
并且在查询中,您还可以为 IsDeleted
添加表达式。
请看这里:Generic Repository Pattern - Entity Framework, ASP.NET MVC and Unit Testing Triangle
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
除外)。您编写的所有逻辑和代码都必须用表达式节点表示。
有一种方法 PropertyOrField
可以从特定表达式中读取 属性 的值。在这种情况下,我们从参数中读取它(即 d => d.isDeleted
- 我们正在编写 d.isDeleted
部分)。然后我们需要将值与 false 进行比较。
最后,我们简单地And
我们的原始表达式,并使用原始参数创建一个 lambda。
您可以将方法更改为:
public T GetSingle(param Expression<Func<T, bool>>[] expression)
使用数组,关键字param.
您可以发送两个、三个、四个或任意数量的参数。