2009-10-26 120 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的传统数据库时,请遵守简单的原则。