在我正在开发的项目中,我们将一个规范(由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表达式构建一个标准,该表达式对主实体的子集合进行操作?
答案 0 :(得分: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)