In the project I am working on, we are passing a specification (ala the Specification pattern as put forward by Martin Fowler) to a repository that uses NHibernate as its backend. The predicates to determine whether a given object are implemented as lambdas wrapped as Expressions, which the repository hands off to the Criteria API in NHibernate to actually fetch the result.
What we have looks something like:
class MySpecification : ISpecification<AnEntity>
{
public Expression<Func<AnEntity, bool>> Satisfies
{
get { return entity => entity.Children.Count(c => !c.IsDeleted) == 0; }
}
}
and in the repository:
public IEnumerable<AnEntity> Select(ISpecification<AnEntity> spec)
{
ICriteria criteria = Session.CreateCriteria<AnEntity>();
criteria.Add(NHibernate.Criterion.Expression.Where(spec.Satisfies));
return criteria.List<AnEntity>();
}
At runtime, we get exceptions of the form:
{variable 'entity' of type 'AnEntity' referenced from scope '', but it is not defined"} System.Exception {System.InvalidOperationException}
When we reduce the predicates to simple boolean expressions that perform no set operations (e.g. Any, Count, Where) on child collections, everything works fine.
With that in mind, is there any way to build a criterion using a lambda expression that operates on the child collections of the main entity?
It is not possible to do such things with Criteria API. You are trying to mix Linq and Criteria API. Criteria API has own methods to work with child collection.
You could achieve what you want using linq-to-nhibernate. Try to change your method like following
Queryis an extension methodNHibernate.Linq.LinqExtensionMethods.Query(this ISession session)