0

在我正在进行的项目中,我们将一个规范(也就是 Martin Fowler 提出的规范模式)传递给一个使用 NHibernate 作为其后端的存储库。用于确定给定对象是否实现为包装为表达式的 lambda 的谓词,存储库将其传递给 NHibernate 中的 Criteria API 以实际获取结果。

我们所拥有的看起来像:

class MySpecification : ISpecification<AnEntity>
{
      public Expression<Func<AnEntity, bool>> Satisfies
      {
           get { return entity => entity.Children.Count(c => !c.IsDeleted) == 0; }
      }
}

并在存储库中:

public IEnumerable<AnEntity> Select(ISpecification<AnEntity> spec)
{
      ICriteria criteria = Session.CreateCriteria<AnEntity>();
      criteria.Add(NHibernate.Criterion.Expression.Where(spec.Satisfies));
      return criteria.List<AnEntity>();
}

在运行时,我们得到以下形式的异常:

{variable 'entity' of type 'AnEntity' referenced from scope '', but it is not defined"} System.Exception {System.InvalidOperationException}

当我们将谓词简化为对子集合不执行集合操作(​​例如 Any、Count、Where)的简单布尔表达式时,一切正常。

考虑到这一点,有没有办法使用对主实体的子集合进行操作的 lambda 表达式来构建标准?

4

1 回答 1

1

使用 Criteria API 无法执行此类操作。您正在尝试混合 Linq 和 Criteria API。Criteria API 有自己的方法来处理子集合。

您可以使用 linq-to-nhibernate 实现您想要的。尝试更改您的方法,如下所示

public IEnumerable<AnEntity> Select(ISpecification<AnEntity> spec)
{
    return Session.Query<AnEntity>() 
        .Where(spec.Satisfies)
        .ToList();
}

Query是一种扩展方法NHibernate.Linq.LinqExtensionMethods.Query(this ISession session)

于 2012-08-01T18:40:31.463 回答