ORM - 使用关联创建对象

时间:2009-10-26 12:23:27

标签: orm

一个对象与许多其他对象相关联:

示例:一个PostBlog的一部分,有一个与Tags的关系列表,以及许多其他内容......

然后我有一个带有下拉框的Web表单,每个表单都填充自定义查询以仅检索该对象的Id和Name,我没有获得所有对象,因为它可以具有大的值(不要问我为什么,但它可能发生),也因为我不需要其他属性来构建下拉框。

现在当我尝试创建这个新的Post时,我需要做这样的事情:

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

在ORM之前我可以使用SQL查询来创建对象并仅传递博客的ID,但现在我需要传递博客对象。这意味着我需要从DB中检索它才能创建帖子,这篇文章还需要标签对象和其他东西。我认为这是一项不必要的操作。为什么我需要让所有其他对象创建其他对象?

有一个类似的问题here,但没有接受答案。

由于我之前解释过的原因,我也不会从下拉框中缓存对象。

我想创建此post仅传递Id的{​​{1}}。有没有办法做到这一点?

注意:使用NHibernate,但我认为这是一般的ORM问题。

4 个答案:

答案 0 :(得分:1)

您可以使用投影类。仅检索您需要的信息,而不是检索完整的DB记录。

一个例子:

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>();

答案 1 :(得分:0)

在ORM中,您可以按照自己的意愿行事:
仅使用部分填充的博客创建帖子。

这是非常普通的代码:

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

如果多次使用,有明显的方法来减少此代码。 我把它留给你作为练习; - )


请注意,它会触发其他问题。 例如,当您处理博客时,它已完全初始化?

答案 2 :(得分:0)

正确:如果ORM支持延迟提取(hibernate确实),则sess.load(class,id)实际上不会生成任何SQL查询,但会返回未初始化的代理。

答案 3 :(得分:0)

对于Hibernate(不是NHibernate,但它应该类似)我相信你通常可以使用HQL查询来加载对象:

select id from Blog where ...

您可以将其加载到Blog对象中,它将以透明方式工作。如果您随后访问了未加载的任何属性,它将触发对其余内容的查询(如果您将对象传递到其会话范围之外,则触发LazyInitializationException)。

收藏和关联通常也会延迟加载。简单参数类型的情况有点复杂,我认为没有一种简单的方法可以做到这一点。如果您发现自己映射了大量数据(即CLOB或BLOB),您可能想要作弊并使用关联映射它。

在任何情况下,只是因为你已经为你做了转换的ORM框架,并不意味着你可以免除所有关于如何加载对象的细节。事实上,正确获取数据访问层是最棘手的挑战之一。特别是当使用不太适合Hibernate的遗留数据库时,请保持简单的原则。