2016-05-12 33 views
3

我想找到使用做這樣的事情時,從數據庫中獲取數據的這三種方式的區別:NHibernate的差異,獲取<T>和負載<T>

public T GetById(int id) { 
    using (var db = Database.Session) { 
     using (var t = db.BeginTransaction()) { 
      try { 
       return db.Get<T>(id); 
      } 
      catch (Exception) { 
       if (!t.WasCommitted) { 
        t.Rollback(); 
       } 
       throw; 
      } 
     } 
    } 
} 

public T GetById(int id) { 
    using (var db = Database.Session) { 
     using (var t = db.BeginTransaction()) { 
      try { 
       return Query<T>().First(x=>x.Id == id); 
       //or something like 
       //return Query<T>().Where(x=>x.Id == id).FirstOrDefault(); 
       //or 
       //return QueryOver<T>().Where(x=>x.Id == id).FirstOrDefault; 
      } 
      catch (Exception) { 
       if (!t.WasCommitted) { 
        t.Rollback(); 
       } 
       throw; 
      } 
     } 
    } 
} 

甚至這樣說:

​​

另外還有一個問題,Query()QueryOver()有什麼不同?

我在這裏閱讀了一些在stackoverflow的答案,但由於其中大部分是關於開始使用Linq和NHibernate 3,我想知道今天的情況如何。

+0

也許[這](https://ayende.com/blog/3988/nhibernate-the-difference-between- get-load-and-query-by-id)可以幫助你嗎? – SeM

回答

2

類似try to explain it is here

一般來說我們有三種方式可以由它的編號來獲得從數據庫實例。

1)查詢 - 這是我們使用QueryOver API(原生NHibernate語言)或查詢(實現MS LINQ API)的地方。這些查詢總是打DB(或高速緩存),能夠加載全根對象,獲取一些關係,或只是投影(僅幾列/屬性轉換成一些DTO)

2)然後,我們有Get<TEntity>(),其目的是作爲如何通過ID獲取物品的最常見方式。它總是命中DB因爲合同其說(get):

返回與給定的標識符指定的實體類,或的持久化實例,如果不存在這樣的持久化實例

因此,爲了確保該對象是否存在,必須擊中數據庫。

3)最後,還有第三個合同-Load<TEntity>()。它永遠不會打DB,以檢查是否有這樣一個項目(與提供的ID)load()

返回與給定的標識符指定的實體類的持久化實例,假設實例存在。

如果我們有一個參考ID,並且我們知道它確實存在,我們應該使用Load<TEntity>()

它將只是創建一個代理 - 與設置ID和根/保持器實體的插入或更新的過程中,代理ID將被用於創建正確的SQL語句。

總結:Get()Load()是有我們的原因。它們旨在支持不同的場景。

參見:

1

Query()與QueryOver()的區別?

QueryOver是Criteria的強類型版本,更具體的NHibernate。幾乎任何你可以在ICriteria中做的事情都可以使用QueryOver完成。在ICriteria NH2的黃金時段,你總是必須施放,因此這就是爲什麼現在你需要在鏈的末尾回到int。

LINQ(查詢)是一種標準的查詢方法,適用於IQueryable,不需要顯式引用NHibernate,可以考慮更多的ORM不可知,因此遵循linq標準。正如你正確地指出,你不需要投入到一個int,因爲你正在選擇結果customNumber。