2011-05-26 92 views
28

作爲nHibernate及其實用程序庫的新用戶,流利的nhibernate,我試圖學習足夠危險的數據庫。有人能更好地解釋nHibernate中的'Projections'是什麼嗎?

我對理解投影這個概念的難度特別大。具體而言,他們是什麼世界?

我已經做了字面上的「什麼是預測準確的搜索?「和」 項目NHibernate的「和」 NHibernate的,預測,定義」等。而我仍然很困惑。到目前爲止最有用的帖子是This other StackOverflow QuestionThis Blog Post by Colin Ramsay。但我仍然非常困惑。我對數據庫的瞭解仍然是入門級的。

我真的不明白是什麼預測,爲什麼我想要使用它們,他們正在完成什麼等。我在博客文章中看到他正在使用它們來獲取整數列表(我假定主鍵),以便他可以在不同的查詢中使用它們,但是它的運作方式和原因都是模糊的。

回答

67

這裏有一個實際的例子。

假設你有一個在線商店,你的域類之一是Brand如「三星」。這個類具有與它相關聯的屬性,可能的整數Identity,一個Name,自由文本字段Description,到Vendor對象的引用,等等的一船。

現在,讓我們說,你想在你的網上商店提供的所有品牌的列表中顯示的菜單。如果你只是做session.CreateCriteria<Brand>().List(),那麼你確實會得到所有的品牌。但是您也可以從數據庫中吸取所有長Description字段和對Vendor的引用,並且不需要顯示菜單;你只需要NameIdentity。性能方面,從數據庫中吸收所有這些額外的數據會減慢速度並且不必要。

相反,你可以創建一個「投影」對象只包含IdentityName調用它,也就是說,NameIdentityPair

public class NameIdentityPair 
{ 
    public int Identity { get; set; } 
    public string Name { get; set; } 
} 

你能告訴NHibernate的,只選擇你真正需要的數據告訴它的結果集轉換到您的投影來執行手頭的任務:

var brandProjections = this.session.CreateCriteria<Brand>() 
    .SetProjection(Projections.ProjectionList() 
     .Add(Projections.Property("Name"), "Name") 
     .Add(Projections.Property("Identity"), "Identity")) 
    .SetResultTransformer(Transformers.AliasToBean<NameIdentityPair>()) 
    .List<NameIdentityPair>(); 

foreach (var brandProjection in brandProjections) 
{ 
    Console.WriteLine(
     "Identity: {0}, Name: {1}", 
     brandProjection.Identity, 
     brandProjection.Name); 
} 

現在你沒有的Brand個清單,但代替列表s,而NHibernate將只發佈一個SQL語句,如SELECT b.Identity, b.Name from dbo.Brand b來獲得此投影,而不是大量的SQL語句,該語句抓取所有必需的東西來保存對象(例如SELECT b.Identity, b.Name, b.Description from dbo.brand b left join dbo.vendor v ....)。

希望這會有所幫助。

+2

所以投影就像查詢方限制器,查詢結果限制器的intead。在正常情況下,我會創建NameIdentityPair對象,並將查詢中的結果映射到查詢中,但是使用Projection時,我會指定恰好在查詢中要求的確切過濾條件,這是數據庫意識到的所有問題? – Derek 2011-05-26 15:25:52

+4

許多應用程序的讀取次數比寫入次數多,因此常見模式是在從數據庫中讀取時使用投影,並使用完全水合的域對象保存到數據庫。通過這種方式,從數據庫中讀取數據會根據性能進行調整,並且寫入數據庫將被調整爲利用業務邏輯(寫入您的域類)和您正在使用的工具(NHibernate將您從大多數CRUD代碼中拯救出來)。 「投影」就像是抽出你需要的數據,這樣NHibernate只會在數據庫提交SQL時向數據庫請求數據。 – 2011-05-26 15:31:06

+0

謝謝,我認爲這比迄今爲止發現的要清楚得多。 – Derek 2011-05-26 16:17:50

1

您可以使用投影調用SQL功能,如SUM,COUNT ...,或選擇單個字段,而返回的實體。

「...僅檢索一個或多個實體的屬性,沒有將實體本身加載到事務範圍中的開銷,有時稱爲報告 查詢;它更正確地稱爲投影。 [NHibernate in Action]

2

如果您熟悉SQL,則投影是查詢的SELECT子句,用於從可用結果中選擇要返回的字段。

例如,假設你有一個PersonFirstNameLastNameAddressPhone領域。如果您希望查詢返回所有內容,則可以忽略投影,這與SQL中的SELECT * FROM Person類似。如果您只想要姓和名,可以使用FirstNameLastName來創建投影 - 這將是SQL中的SELECT FirstName, LastName FROM Person

相關問題