2011-08-24 100 views
2

这个问题是接近但不一样的一个位置: NHibernate Query across multiple tablesNHibernate的析取(“OR”)查询在许多-to-one和许多一对多关系

基本上,我的问题是给定的以下模型中,我将如何查询以查明当前狗是否具有名称“foo”或过去的狗名称是“foo”(分离)。 本质上,我有一个多对一的CurrentDog关系和一个多对多关系的PastDogs。

public class Dog { 
    public string name {get; set;} 
} 

public class Owner { 
    public string firstname {get; set;} 
    public string lastname {get; set;} 
    public Dog CurrentDog {get; set;} 
    public Dog[] PastDogs {get; set;} 
} 

我猜的SQL应该是这个样子:

SELECT o.* FROM owners AS o 
    INNER JOIN dogs AS cd ON o.current_dog_id = cd.id 
    INNER JOIN owner_past_dog_maps AS pd ON o.id = pd.owner_id 
    INNER JOIN dogs AS d ON pd.dog_id = d.id 
    WHERE d.name = 'foo' 
    OR cd.name = 'foo' 

希望是有道理的......我试试,如果有人问澄清。

+0

我想我可以把它放在一个新的帖子中,但这个问题的扩展将是如何返回一个拥有者曾经拥有,过去或现在的所有狗? – longda

回答

4

我已经尝试使用QueryOver和别名

Owner myOwner = null; 
Dog myCurrentDog = null; 
Dog myPastDogs = null; 

var sax = _HibSession.QueryOver<Owner>(() => myOwner) 
       .JoinAlias(() => myOwner.CurrentDog,() => myCurrentDog, JoinType.InnerJoin) 
       .JoinAlias(() => myOwner.PastDogs,() => myPastDogs , JoinType.InnerJoin) 
       .Where(Restrictions.Disjunction() 
        .Add(Restrictions.EqProperty(myCurrentDog.Name,"foo")) 
        .Add(Restrictions.EqProperty(myPastDogs.Name,"foo"))      
       )            
       .List<Owner>(); 

解决,我希望是有帮助!

+0

哦,很酷。不同的方式做它我猜...使用QueryOver模式有好处吗? – longda

+1

我总是使用QueryOver模式,因为没有字符串放在代码中(比如.Restrictions.Eq(“cd.Name”,“foo”)作为Criteria模式)。因此,我减少了编写导致运行时错误的错误字段名的概率(例如.Restrictions.Eq(“cd.NaNe”,“foo”)仅在运行时抛出异常)。享受QueryOver! :-) – Faber

+0

这里有一些潜力的例子http://nhforge.org/blogs/nhibernate/archive/2009/12/17/queryover-in-nh-3-0.aspx – Faber

0

我想我应该从NHibernate的新手开始。我不明白的是在NHibernate中出现的别名,并且你正在创建不是用于表的别名,而是用于关系和属性名的别名。看哪,这将返回所有谁拥有或有一只狗的名字foo的业主解决方案:

var output = Session.CreateCriteria<Owner>() 
     .CreateAlias("CurrentDog", "cd") 
     .CreateAlias("PastDogs", "pd") 
     .Add 
     (
      Restrictions.Disjunction() 
      .Add(Restrictions.Eq("cd.Name", "foo")) 
      .Add(Restrictions.Eq("pd.Name", "foo")) 
     ) 
     .List<Owner>();