如何在Expression <func <t,bool =“”>&gt;中添加额外参数Generic Repository中的谓词

时间:2016-01-11 10:12:36

标签: c# asp.net-mvc repository-pattern predicate unit-of-work

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

这是我从db获取单个记录的原始方法。

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)))

4 个答案:

答案 0 :(得分:3)

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。

答案 1 :(得分:2)

看看PredicateBuilder,特别是&#34; Generic Predicates&#34;解释如何创建通用约束以过滤项目的部分

答案 2 :(得分:2)

您可以拥有BaseEntity,其中包含IsDeleted属性。

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

现在在存储库中,

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

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

请在这里查看:Generic Repository Pattern - Entity Framework, ASP.NET MVC and Unit Testing Triangle

答案 3 :(得分:0)

您可以将方法更改为:

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

使用数组和关键字 param

您可以发送两个,三个,四个或任何数量的参数。