2011-02-04 73 views
0

我的DTO有一個由我的數據庫使用的ID,通常是自動遞增的INT。一般來說,我的應用程序並不關心這個ID字段,它傾向於通過它們的Name屬性來查找DTO。這已經產生了這種方法在我的數據訪問層:nHibernate Session.Load屬性名稱

public T GetByName(string name) 
{ 
    return (T) Session 
     .CreateCriteria(typeof (T)) 
     .Add(Expression.Eq("Name", name)) 
     .UniqueResult(); 
} 

現在,我已經注意到了,因爲這是我如何加載絕大多數我的DTO的是,NHibernate的不緩存結果。我已經能夠通過SQL Profiler觀察到,每次調用此方法都會導致數據庫往返,即使我確定在單元工作期間已經加載了這個特定對象(一個HTTP事務)。

此外,我讀到的是,當您調用.Load()時,nHibernate會將DTO緩存在第一級緩存中。

所以,我的問題是:有沒有辦法配置nHibernate把我的DTOs加載到第一級緩存後,這樣加載,還是我需要找到另一種方式來減少我的數據庫往返?

回答

2

您的代碼有幾個問題。

  1. 標準將總是去到DB,除非你緩存查詢。您需要使用SetCacheable,配置緩存提供程序和enable query caching
  2. 即使您緩存查詢,您仍然需要make the entity cacheable,因爲NHibernate存儲從該查詢得到的對象id,而不是實體本身。
  3. 所謂的「第一級緩存」是工作單元(會話)。您使用GetLoad方法與其進行交互,而不是查詢。小例外:實體中已經加載的會話不需要再次從DB中讀取。
0

NHibernate不會將您的實體緩存在第一級緩存中,除非您通過主鍵加載它們。

我以前也有過這種情況。我從來沒有確定未通過主鍵加載的實體是否會緩存在二級緩存中(如果您使用的是)。也許別人可以提供答案。

+0

通過二級緩存配置確定緩存在二級緩存中的內容。在這種情況下,查詢結果緩存需要打開,因爲您實際上正在執行查詢來檢索對象。 – 2011-02-04 17:03:43

0

如果將自然標識定義爲名稱字段,那麼該怎麼辦?我不知道nHibernate是否只是將它用於模式生成,但它是有道理的,這是定義它的一個自然的地方,無論nHibernate實際上會用它來做什麼。如果不是,這不是一個不好的功能請求。