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
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)