ORM-创建具有关联的对象

ORM-创建具有关联的对象,orm,Orm,一个对象与多个其他对象关联: 示例:一篇文章是一篇博客的一部分,有一个与标签的关系列表,以及许多其他内容 然后我有一个带有下拉框的web表单,每个表单都是从自定义查询中填充的,只检索该对象的Id和名称,我没有得到所有对象,因为它可以有大的值(不要问我为什么,但可能会发生),而且我不需要其他属性来构建下拉框 现在,当我尝试创建新的Post时,我需要执行以下操作: Post post = new Post(); post.Blog = blog; ..... 在ORM之前我可以使用SQL查询创建对

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

示例:一篇
文章
是一篇
博客
的一部分,有一个与
标签
的关系列表,以及许多其他内容

然后我有一个带有下拉框的web表单,每个表单都是从自定义查询中填充的,只检索该对象的Id和名称,我没有得到所有对象,因为它可以有大的值(不要问我为什么,但可能会发生),而且我不需要其他属性来构建下拉框

现在,当我尝试创建新的
Post
时,我需要执行以下操作:

Post post = new Post();
post.Blog = blog;
.....
在ORM之前我可以使用SQL查询创建对象并只传递blog的Id,但是现在我需要传递blog对象。这意味着我需要从数据库中检索它来创建文章,而这篇文章还需要标记对象和其他东西。我认为这是不必要的行动。为什么我需要让所有其他对象创建其他对象

有一个类似的问题,但没有公认的答案

出于我前面解释的原因,我也不会缓存下拉框中的对象

我想创建这个
帖子
只传递
博客
Id
。有没有办法做到这一点


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

在ORM中,您可以随心所欲:
仅使用部分填充的博客创建帖子

这是非常普通的代码:

    Post post = new Post();
    post.setBlog(new Blog(123));
如果多次使用,有明显的方法可以减少此代码。 我把这个留给你做练习;-)


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

对:如果ORM支持延迟抓取(hibernate支持),sess.load(class,id)实际上不会生成任何SQL查询,而是返回一个未序列化的代理。

对于hibernate(不是NHibernate,但应该类似)我相信您通常可以按如下方式使用HQL查询来加载对象:

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

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


在任何情况下,仅仅因为您有ORM框架为您进行转换,并不意味着您可以免除所有关于如何加载对象的小细节。事实上,正确使用数据访问层是最困难的挑战之一。尤其是在使用不太符合Hibernate的保持简单原则的遗留数据库时。

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

一个例子:

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>();
HqlBasedQuery query=新的HqlBasedQuery(typeof(Post),
@"
选择tags.Id、tags.Name
邮寄
内部连接post.Tags
其中post.Id=?
按标签排序。名称
“,posted);
var results=来自(ArrayList)ActiveRecordMediator.ExecuteQuery(查询)中的对象[]摘要
选择新建ProjectionClass
{
Id=(int)摘要[0],
名称=(字符串)摘要[1],
};
返回结果。ToList();