Question

My fluent nHibernate mapping as follows

public class FilmMap : ClassMap<Film> 
{
    public FilmMap()
    {
        Id(x => x.FilmId, "film_id");
        Map(x => x.Description);
        Map(x => x.Title, "title");
        base.HasMany<FilmActor>(x => x.FilmChildActors).Where(x => x.Actor.Age < 16 ); 
    }
}

public class FilmActorMap : ClassMap<FilmActor>
{
    public FilmActorMap()
    {
        Table("film_actor");
        CompositeId()
            .KeyProperty(x => x.ActorId, "actor_id")
            .KeyProperty(x => x.FilmId, "film_id");
        Map(x => x.LastUpdate, "last_update");
        References<Actor>(x => x.Actor, "actor_id").Fetch.Join();
    }
}

public class ActorMap : ClassMap<Actor>
{
    public ActorMap()
    {
        Id(x => x.ActorId, "actor_id");
        Map(x => x.FirstName, "first_name");
        Map(x => x.LastName, "last_name");
        Map(x => x.Age, "Age");
      }
}

Getting the following exception at the time building the session factory

System.InvalidOperationException occurred
  HResult=-2146233079
  Message=variable 'x' of type 'NhibernateTestProj.FilmActor' referenced from scope '', but it is not defined
  Source=System.Core
  StackTrace:
       at System.Linq.Expressions.Compiler.VariableBinder.Reference(ParameterExpression node, VariableStorageKind storage)
       at System.Linq.Expressions.Compiler.VariableBinder.VisitParameter(ParameterExpression node)
       at System.Linq.Expressions.ParameterExpression.Accept(ExpressionVisitor visitor)
       at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
       at System.Linq.Expressions.ExpressionVisitor.VisitMember(MemberExpression node)
       at System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)
       at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
       at System.Linq.Expressions.ExpressionVisitor.VisitMember(MemberExpression node)
       at System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)
       at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
       at System.Linq.Expressions.Compiler.VariableBinder.VisitUnary(UnaryExpression node)
       at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
       at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
       at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
       at System.Linq.Expressions.Compiler.VariableBinder.VisitLambda[T](Expression`1 node)
       at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
       at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
       at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda, DebugInfoGenerator debugInfoGenerator)
       at System.Linq.Expressions.Expression`1.Compile()
       at FluentNHibernate.Utils.ExpressionToSql.Convert[T](Expression`1 expression, MemberExpression body) in D:\Renand\Download\jagregory-fluent-nhibernate-1.4.0.1-7-g65884f1\jagregory-fluent-nhibernate-65884f1\src\FluentNHibernate\Utils\ExpressionToSql.cs:line 54
  InnerException:

Edit1: One more finding

If I use

base.HasMany<FilmActor>(x => x.FilmChildActors).Where(x => x.ActorId = 16 ); 

then it adds the where condition in the sql as (filmactors.ActorId = 1), since ActorId is not there in the database it throws exception.

Please let me know how to solve this problem

Was it helpful?

Solution

The issue is here .Where(x => x.Actor.Age < 16 ) in the mapping

base.HasMany<FilmActor>(x => x.FilmChildActors).Where(x => x.Actor.Age < 16 ); 

This part is intended as a pure SQL Statement

.Where("SQL command") // or an boolean lambda expression

We can work there only with the content of the table containing the collection data. There is no way how to work with the Actor.Age... just with the ActorId.

But we can create a more complex SQL Statement, selecting those ActorIds, which are in some subselect

.Where("ActorId IN (SELECT a.ActorID FROM film_actor a ....

And in that case we can pass even some params like WHERE a.actor_id = actor_id, where the second actor_id is passed as param

For example check this QA How to Fluently map with constraint in HasMany

Also check the 6.2. Mapping a Collection, an extract:

where="" (optional) specify an arbitrary SQL WHERE condition to be used when retrieving or removing the collection (useful if the collection should contain only a subset of the available data)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top