0

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

然而,一个“活动”并不与所有用户相关,为了确定关系,我们有一段复杂的代码。

这是我的活动课

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 个活动,我将获得另外 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;
    }
}

编辑:这是 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();
    }
}
4

2 回答 2

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() -

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

来源 -链接

于 2011-03-31T18:09:44.067 回答
2

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

于 2011-03-31T18:09:50.357 回答