在传递给NHibernate';s标准API

本文关键字:标准 API NHibernate | 更新日期: 2024-09-20 14:11:36

在我正在进行的项目中,我们将一个规范(类似于Martin Fowler提出的规范模式)传递给一个使用NHibernate作为后端的存储库。用于确定给定对象是否实现为包装为表达式的lambdas的谓词,存储库将其交给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表达式来构建标准?

在传递给NHibernate';s标准API

使用Criteria API不可能做到这一点。您正在尝试混合Linq和Criteria API。条件API有自己的方法来处理子集合。

你可以使用linq来实现你想要的。试着像下面的一样改变你的方法

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

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