【问题标题】:NHibernate: Lazyload single propertyNHibernate:延迟加载单个属性
【发布时间】:2010-07-24 12:09:18
【问题描述】:

我目前已将我的博客引擎从 Linq2Sql 转移到 NHIbernate。

我遇到了以下性能问题: 我有一个表:'Posts',它有 Id、Title、PostContent、DateCreated 列等等。

问题是,当我创建“最近的帖子列表”时,我不想要整个 PostContent

在 Linq2Sql 中,您可以对单个属性设置延迟加载,因此在您实际请求该属性之前,它不会成为 SQL 查询的一部分。

我尝试使用 Fluent NHibernate 执行此操作,方法如下:

Map(x => x.PostContent).LazyLoad();

没有成功。谷歌搜索,似乎 NHibernate 不支持这个,所以我的问题是,我该如何解决这个问题?

真的不能在不将内容移动到单独的表格的情况下延迟加载我的属性吗?

提前致谢!

【问题讨论】:

  • 我还尝试创建一个名为 PostContent 的类,其中包含一个 value 属性,并使用以下方法对其进行映射: Component(x => x.PostContent, m => m.Map(x => x .Value).Column("PostContent")).LazyLoad();也没有用:/

标签: nhibernate lazy-loading


【解决方案1】:

更新:NHibernate 主干现在提供此功能。

查看Ayende's blog 的详细信息,其中的示例正是您在此处描述的场景。

【讨论】:

  • “目前仅在使用 Castle Proxy Factory 时可用”是什么意思?
  • @Louis NHibernate 可以配置为使用 Castle.DynamicProxy 或 LinFu.DynamicProxy。您几乎肯定已经在使用 Castle。
【解决方案2】:

这里是你如何实现你想要的(一种延迟加载,但不一样)

var posts = NHibernateSessionManager.Session.CreateQuery("Select p.Id as Id, p.Title as Title, p.DateCreated as DateCreated from Post p")
                .SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean(typeof(Post)))
                .List<Post>();

AliasToBean 的用途是对特定列(通常来自多个实体)进行选择并返回强类型集合而不是 System.Object[]。

现在,如果您的 Bean(类)是您的 Post 类,那么它将仅填充到该类中请求的列,而不是其他任何内容。

您不会拥有的是 NHibernate 托管对象的集合。返回列表中的所有帖子都是分离的非受控对象。

对于执行诸如“获取所有最近的帖子”之类的事情,而不必获取实体的最“重量级”列,同时不必创建其他类来将数据转换为,上述解决方案是完美的。

查看更多信息: NHibernate: returning a strongly typed list having applied an aggregate function

【讨论】:

  • 谢谢!这真的让我前进了。顺便说一句,很抱歉回复缓慢。我想知道我应该如何使用这种方法处理缓存?据我了解,我无法在第二层缓存中缓存任何东西,如果它像你说的那样分离。
  • 没问题...我相信这些对象仍在二级缓存中。由于我不确定,也许您可​​以通过测试(单元测试或仅通过调试对相同代码的第二个请求以查看查询是否再次访问数据库)来找出答案 - 当然应该启用缓存在 Post 映射文件中)。
  • 我实际上是这样做的,而且似乎一旦我使用 ResultTransfomer,集合就会变得不可缓存:/
  • 在上面的查询中要添加的重要一点是,确保您有别名,否则您将收到“Could not find a setter for property '0' in class”
【解决方案3】:

这在 PostContent 映射到同一个表时是不可能的,因为在 99% 的情况下性能差异并不显着。当你处于 1% 的时候,你可以考虑使用 handbuild sql 而不是 orm。

据我所知,使用 linq to sql(开箱即用)根本不可能进行延迟/急切加载。

您可以用您想要选择的数据创建一个不同的类,然后将该数据选择到一个新对象中。

【讨论】:

  • 嗯,好吧。听起来像一个解决方案。你能举个小例子说明你会怎么做吗?
  • 延迟/急切加载 可以使用 LinqToSql。它只是不如 NHibernate 灵活。
  • 首先,我将启动一个分析器并找到代码中最慢的部分。比我先优化那部分。比重复直到足够快。当足够快的速度低于 1/1000 秒时,我会点击查询的一部分,我会写成 session.Linq().Select(post => new RecentPost(post.Property1, post.Property2 ).Take(10).ToList();
  • 根据要求,一个很好的(几乎相同的)示例,至少关于设置映射,在这里:blogs.hibernatingrhinos.com/nhibernate/archive/2008/11/17/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多