Fluent Nhibernate Lazy是否从Criteria加载IList

时间:2011-03-31 17:28:37

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

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

但是,“活动”与所有用户无关,为了确定关系,我们有一段复杂的代码。

这是我的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条新闻。但由于活动表非常庞大,性能问题,我想做最好的练习。

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

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;
    }
}

修改: 这是活动模型的ActivityMapping。

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

2 个答案:

答案 0 :(得分:3)

如果您的问题是关于生成的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会立即将所有记录加载到内存中。

[更新] 如果您需要逐个返回记录,请使用Enumerable() -

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

来源 - Link

答案 1 :(得分:2)

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