2009-10-26 123 views
2

一個對象與其他許多相關:ORM - 創建關聯對象

例子:一個Post是一個Blog的一部分,有關係的有Tags列表,以及許多其他的事情.....

然後我有一個帶有下拉框的web窗體,每個窗體都從一個自定義查詢中填充以僅檢索該對象的ID和名稱,我沒有獲得所有對象,因爲它可以具有大尺寸值(不要問我爲什麼,但它可能會發生),也因爲我不需要其他屬性來構建下拉框。

現在,當我嘗試創建新Post我需要做這樣的事情:

Post post = new Post(); 
post.Blog = blog; 
..... 

ORM之前,我可以使用SQL查詢來創建對象,並通過博客的唯一編號, 但現在我需要傳遞博客對象。這意味着我需要從數據庫中檢索它來創建帖子,而這篇文章也需要標籤對象和其他東西。我認爲這是不必要的操作。爲什麼我需要獲得所有其他對象來創建其他東西?

還有一個類似的問題here但沒有接受答案。

由於我之前解釋過的原因,我也不會從下拉框中緩存對象。

我想創建此post只通過blogId。有沒有辦法做到這一點?

注意:使用NHibernate,但我認爲這是一般的ORM問題。

回答

1

您可以使用投影類。僅檢索您需要的信息,而不是完整的數據庫記錄。

一個例子:

HqlBasedQuery query = new HqlBasedQuery(typeof(Post), 
     @" 
     SELECT tags.Id, tags.Name 
     FROM Post post 
     INNER JOIN post.Tags tags 
     WHERE post.Id = ? 
     ORDER BY tags.Name 
     ", postId); 
     var results = from object[] summary in (ArrayList)ActiveRecordMediator.ExecuteQuery(query) 
         select new YourProjectionClass 
         { 
          Id = (int)summary[0], 
          Name= (string)summary[1], 
         }; 
     return results.ToList<YourProjectionClass>(); 
0

在ORM中,您可以按照自己的意願進行操作:
僅使用部分填充的博客創建帖子。

這是非常普通的代碼:

Post post = new Post(); 
    post.setBlog(new Blog(123)); 

如果多次使用,有減少這種代碼明顯的方式。 我離開這個給你作爲一個exercice ;-)


需要注意的是它引發的其他問題。 例如,當您處理博客時,它已完全初始化?

0

右:如果ORM支持懶取(hibernate確實),sess.load(class,id)實際上並不會生成任何SQL查詢,但會返回一個未經初始化的代理。

0

對於休眠(非NHibernate的,但它應該是相似的),我相信你通常可以使用HQL查詢如下加載對象:

select id from Blog where ... 

,你可以加載到博客對象,它會工作透明。如果您然後訪問您未加載的任何屬性,則會觸發其餘內容的查詢(或者,如果您將該對象傳遞到其會話範圍之外,則爲LazyInitializationException)。

集合和關聯通常也被延遲加載。簡單參數類型的情況有點複雜,我不認爲有一個簡單的方法來做到這一點。如果您發現自己映射了大量數據(即CLOB或BLOB),則可能需要作弊並使用關聯進行映射。

無論如何,僅僅因爲你已經有ORM框架爲你做轉換,並不意味着你可以免除所有關於如何加載對象的細節。事實上,正確獲取數據訪問層是最棘手的挑戰之一。特別是在使用不太適合Hibernate的傳統數據庫時,請遵守簡單的原則。