2011-08-24 103 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>();