【问题标题】:Does Fluent Nhibernate Lazy loads IList from CriteriaFluent Nhibernate Lazy 是否从 Criteria 加载 IList
【发布时间】:2011-03-31 17:28:36
【问题描述】:

我想在我公司的应用程序中制作一种“新闻提要”。 在该场景中,用户操作将生成不同类型的“活动”,其他用户将在他们的“新闻提要”中看到。

但是,“Activity”并不与所有用户相关,要确定关系,我们有一段复杂的代码。

这是我的活动课

public class Activity: IActivity
{
    public virtual int Id { get; set; }
    public virtual ActivityType Type { get; set; }
    public virtual User User { get; set; }
    public virtual bool IsVisibleToUser(User userLook)
    {
        // Complex business calculation etc.
        return true;
    }
}

我想获取用户可见的最新 10 条新闻。但是由于 Activity 表会非常大,而且性能是一个问题,所以我想对其进行最佳实践。

我要做的是获取最后 25 个活动,并检查我们是否填写列表以显示给用户。例如,如果用户只能看到 5 个 Activity,我将获得另外 25 个 Activity,依此类推。

IList<Activity> resultList = session.CreateCriteria(typeof(Activity))
                                .SetMaxResults(25)
                                .AddOrder(Order.Desc("Id"))
                                .List<Activity>();

我想知道,如果我得到按 Id 排序的整个列表,并一一检查它是否对用户可见,NHibernate 是否只会加载我使用的对象?

IList<Activity> resultList = session.CreateCriteria(typeof(Activity))
                                .AddOrder(Order.Desc("Id"))
                                .List<Activity>();

int count = 0;
foreach( Activity act in resultList){
    if (act.IsVisible(CurrentUser)){
        count++;
        // Do something with act
        if (count == 10)
            break;
    }
}

编辑: 这是 Activity 模型的 ActivityMapping。

public class ActivityMap : ClassMap<Activity>
{
    public ActivityMap()
    {
        Id(x => x.Id);
        Map(x => x.Type).CustomType(typeof(Int32));
        References(x => x.User).Nullable();
    }
}

【问题讨论】:

  • 您的 Fluent NHibernate Activity 映射是如何定义的?
  • 问题已更新。映射很简单。

标签: nhibernate fluent-nhibernate lazy-loading criteria-api


【解决方案1】:

如果您的问题是关于生成的 SQL 的外观,我的猜测是:

SELECT 
   this_.Id as Id0_0_, 
   this_.ActivityTypeas ActivityType_0_0_, 
   --Other fields
FROM dbo.ActivityType this_ 
WHERE 
   --condition
ORDER BY 
   --condition

既然你提到活动数量很大,你可以利用 ICriteria 的SetFirstResultSetMaxResult

SetFirstResult(int) 表示您希望获得的第一项的索引,SetMaxResult(int) 表示您希望获得的行数,在您的情况下为 25。

ToList 将一次性加载内存中的所有记录。

[UPDATE]如果需要将记录一个一个返回,使用Enumerable() -

如果您希望查询返回大量对象,但又不希望全部使用它们,则可以从返回 System.Collections.IEnumerable 的 Enumerable() 方法获得更好的性能。迭代器将使用初始 SQL 查询返回的标识符(n+1 选择总数)按需加载对象。

来源 - Link

【讨论】:

  • 感谢您的好评。是否可以将列表的元素一一加载到内存中? NHibernate 有处理该问题的方法或配置吗?
  • 感谢您的快速响应。在我的情况下,可枚举将非常有用。但是,如果 Criteria API 有一个用于相同目的的 Enumerable 方法,那就太好了。
【解决方案2】:

不,List() 方法一次将所有内容都拉入内存。

【讨论】:

  • 好的。我知道了。你知道是否有替代解决方案来实现我想要的?
猜你喜欢
  • 1970-01-01
  • 2013-12-10
  • 2014-09-02
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
  • 1970-01-01
  • 2012-04-29
  • 2011-05-09
相关资源
最近更新 更多