ORM - 创建关联对象
一个对象与其他许多相关:ORM - 创建关联对象
例子:一个Post
是一个Blog
的一部分,有关系的有Tags
列表,以及许多其他的事情.....
然后我有一个带有下拉框的web窗体,每个窗体都从一个自定义查询中填充以仅检索该对象的ID和名称,我没有获得所有对象,因为它可以具有大尺寸值(不要问我为什么,但它可能会发生),也因为我不需要其他属性来构建下拉框。
现在,当我尝试创建新Post
我需要做这样的事情:
Post post = new Post();
post.Blog = blog;
.....
ORM之前,我可以使用SQL查询来创建对象,并通过博客的唯一编号, 但现在我需要传递博客对象。这意味着我需要从数据库中检索它来创建帖子,而这篇文章也需要标签对象和其他东西。我认为这是不必要的操作。为什么我需要获得所有其他对象来创建其他东西?
还有一个类似的问题here但没有接受答案。
由于我之前解释过的原因,我也不会从下拉框中缓存对象。
我想创建此post
只通过blog
的Id
。有没有办法做到这一点?
。
注意:使用NHibernate,但我认为这是一般的ORM问题。
您可以使用投影类。仅检索您需要的信息,而不是完整的数据库记录。
一个例子:
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>();
在ORM中,您可以按照自己的意愿进行操作:
仅使用部分填充的博客创建帖子。
这是非常普通的代码:
Post post = new Post();
post.setBlog(new Blog(123));
如果多次使用,有减少这种代码明显的方式。 我离开这个给你作为一个exercice ;-)
需要注意的是它引发的其他问题。 例如,当您处理博客时,它已完全初始化?
右:如果ORM支持懒取(hibernate确实),sess.load(class,id)实际上并不会生成任何SQL查询,但会返回一个未经初始化的代理。
对于休眠(非NHibernate的,但它应该是相似的),我相信你通常可以使用HQL查询如下加载对象:
select id from Blog where ...
,你可以加载到博客对象,它会工作透明。如果您然后访问您未加载的任何属性,则会触发其余内容的查询(或者,如果您将该对象传递到其会话范围之外,则为LazyInitializationException)。
集合和关联通常也被延迟加载。简单参数类型的情况有点复杂,我不认为有一个简单的方法来做到这一点。如果您发现自己映射了大量数据(即CLOB或BLOB),则可能需要作弊并使用关联进行映射。
无论如何,仅仅因为你已经有ORM框架为你做转换,并不意味着你可以免除所有关于如何加载对象的细节。事实上,正确获取数据访问层是最棘手的挑战之一。特别是在使用不太适合Hibernate的传统数据库时,请遵守简单的原则。