使用lambda的流畅的NHibernate的HasMany.Where重载方法在引用子对象属性时给出了异常

时间:2014-01-23 11:57:46

标签: c# nhibernate fluent-nhibernate fluent-nhibernate-mapping

我的流利nHibernate映射如下

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");
      }
}

在构建会话工厂时获得以下异常

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:

编辑1:再找一次

如果我使用

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

然后它将sql中的where条件添加为(filmactors.ActorId = 1),因为在数据库中没有ActorId它会引发异常。

请让我知道如何解决这个问题

1 个答案:

答案 0 :(得分:2)

问题在于映射

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

此部分旨在作为纯SQL语句

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

我们只能使用包含集合数据的表格的内容在那里工作。如果使用Actor.Age无法使用ActorId }。

但我们可以创建一个更复杂的SQL语句,选择那些在一些子选择中的ActorIds

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

在这种情况下,我们甚至可以传递像WHERE a.actor_id = actor_id这样的一些参数,其中第二个actor_id作为参数传递

例如,请检查此质量检查How to Fluently map with constraint in HasMany

同时检查6.2. Mapping a Collection,摘录:

  

where="" (可选)指定在检索或删除集合时要使用的任意SQL WHERE条件(如果集合应包含,则非常有用)只有可用数据的一部分)