我想在我公司的应用程序中制作一种“新闻源”。 在该场景中,用户操作将生成不同类型的“活动”,其他用户将在其“新闻源”中看到。
但是,“活动”与所有用户无关,为了确定关系,我们有一段复杂的代码。
这是我的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();
}
}
答案 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的SetFirstResult
和SetMaxResult
。
SetFirstResult(int)
表示您希望获得的第一个项目的索引,SetMaxResult(int)
表示您希望获得的行数,在您的情况下为25个。
ToList
会立即将所有记录加载到内存中。
[更新] 如果您需要逐个返回记录,请使用Enumerable() -
如果您希望查询返回大量对象,但不希望全部使用它们,则可能会从Enumerable()方法获得更好的性能,这些方法返回System.Collections.IEnumerable。迭代器将使用初始SQL查询返回的标识符按需加载对象(n + 1选择总计)。
来源 - Link
答案 1 :(得分:2)
不,List()方法一次将所有内容都拉入内存。