2014-08-29 99 views
0

好的,我看到过一些类似的问题,但答案要么让我困惑,要么似乎完全过度设计,所以我想问自己的问题。如何使用NHibernate查询具有嵌套属性的对象?

我有一个名为Tree的类,它有一个来自类Plot的对象属性,它具有来自类Year的对象属性,它具有来自类Series的对象属性,该对象属性具有名为Id的字符串属性。这总结如下。

public class Tree { 
    public virtual Plot Plot { get; set; } 
    // other properties... 
} 

public class Plot { 
    public virtual Year Year { get; set; } 
    // other properties... 
} 

public class Year { 
    public virtual Series Series { get; set; } 
    // other properties... 
} 

public class Series { 
    public virtual string Id { get; set; } 
    // other properties... 
} 

每个类对应于数据库的表,和属性对应于外键字段(例如,树木表有一个称为PlotKey字段,其指的是在情节表中的记录)。我想要做的就是加载数据库中所有树,其相应系列的ID为“Adrian_2012”或“IPED Sample”。我认为这将是使用下面的代码很容易服用:

IList<Tree> trees = session.CreateCriteria<Tree>() 
          .Add(Expression.Or(
           Expression.Eq("Plot.Year.Series.Id", "Adrian_2012") 
           Expression.Eq("Plot.Year.Series.Id", "IPED Sample") 
          )) 
          .List<Tree>(); 

但这是抛出:“NHibernate.Exceptions.GenericADOException:无法执行查询”。我尝试过使用Expression.Disjunction,我尝试过使用别名,限制和SimpleExpressions,并且我知道没有任何像未映射的属性或拼写错误的标准发生的愚蠢行为。我见过的唯一可能帮助的是ISession.QueryOver <>()函数,但是我对lambda表达式非常困惑。有没有人有我的解决方案,只会使用一个简单的CreateCriteria <>类似上面的语句?

提前致谢!

回答

2

其中一个不是查询的好方面是Criteria,我们必须明确定义关联链。即我们来介绍JOIN:

你可以很容易通过使用CreateCriteria()导航在互相关联的实体间建立约束。

所以有一个JOIN,我们需要语法这样

var trees = session 
    .CreateCriteria<Tree>() 
    .CreateCriteria("Plot", "p") 
    .CreateCriteria("Year", "y") 
    .CreateCriteria("Series", "s") 
    .Add(Expression.Or(
     Expression.Eq("s.Id", "Adrian_2012") 
     Expression.Eq("s.Id", "IPED Sample") 
    )) 
    .List<Tree>(); 

此外,检查: