2010-11-05 46 views
2

我想通過NHibernate做一個查詢,其中結果的標準取決於引用表的ID。我該怎麼做呢?讓我們來看一個簡單的例子:然後如何用引用的id作爲標準來做NHibernate查詢?

public class Foo 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public Bar ReferencedBar { get; set; } 
}  

public class Bar 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

美孚映射到酒吧:

public class FooMapping : ClassMap<Foo> 
{ 
    public FooMapping() 
    { 
     Id(c => c.Id).GeneratedBy.HiLo("1"); 
     Map(c => c.Name).Not.Nullable().Length(100); 
     References(c => c.Bar); 
    } 
} 

現在我想從它通過ID引用特定的酒吧數據庫中獲取所有Foo的。此功能是通過別的東西,如果你覺得它的使用標準,但請舉例更好:

public IList<Foo> GetAllFoosReferencingBar(int barId) 
{ 
    using (var tx = Session.BeginTransaction()) 
    { 
     var result = Session.CreateCriteria(typeof(Foo)) 
      .Add(Restrictions./* foo.ReferencedBar == id */) // <-- How to add restriction using id? 
      .List<Foo>(); 
     tx.Commit(); 
     return result; 
    } 
} 

當我嘗試這樣做,我得到異常:在NHibernate的

.Add(Restrictions.Eq("ReferencedBar", 32)); 

類型不匹配.Criterion.SimpleExpression:ReferencedBar預期的類型吧,實際類型System.Int32

我沒有參考對象ID爲32尚未欄和不希望創建一個...

回答

1

CreateAlias應該幫助你,就像這樣:

var result = Session.CreateCriteria(typeof(Foo)) 
    .CreateAlias("ReferencedBar", "bar") 
    .Add(Expression.Eq("bar.Id", barId)) 
    .List<Foo>(); 
+0

這工作。我不得不做一些代碼重組,因爲我不能再在同一個列表中將我的id要求傳遞給泛型int要求,但這是成本。 – 2010-11-05 22:58:12

+2

這會導致加入Bar。雖然這會返回正確的結果,但不會執行沒有連接的查詢。 – 2011-08-11 23:20:25

3

如果酒吧是懶loadedable(它在默認情況下),那麼你可以通過「加載」酒吧與它的ID的代理。您可以將該代理實例作爲條件的參考傳遞給Bar:

var result = Session.CreateCriteria(typeof(Foo)) 
    .Add(Expression.Eq("ReferenceBar", Session.Load<Bar>(barId))) 
    .List<Foo>(); 

這會導致您期望的SQL查詢而無需加入Bar。