Fluent Nhibernate Lazy 是否从 Criteria 加载 IList
我想在我公司的应用程序中制作一种“新闻提要”。 在该场景中,用户操作将生成不同类型的“活动”,其他用户将在他们的“新闻提要”中看到。
然而,“活动”并不与所有用户相关,为了确定这种关系,我们有一段复杂的代码。
这是我的 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 个 Activity,并检查我们是否填写了列表以显示给用户。例如,如果只有 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();
}
}
I want to make a kind of "news feed" in the application of my company.
In the scenario, User actions will generate "Activity" of different kinds, and other users will see in their "news feed".
However, an "Activity" is not related to all users, and to determine the relation, we have a complex piece of code.
Here is my Activity class
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;
}
}
I want to get latest 10 news that is visible to User. But since the Activity table will be quite huge, and performance is an issue, I want to do the best practice about it.
What i am about to do, is get 25 last Activity, and check if we fill the list to show to user. For example, if only 5 Activity is visible to user, i will get another 25 Activities and so on.
IList<Activity> resultList = session.CreateCriteria(typeof(Activity))
.SetMaxResults(25)
.AddOrder(Order.Desc("Id"))
.List<Activity>();
I want to learn, if I get the whole list ordered by Id, and check one by one if it is visible to User, would NHibernate only loads the objects that i use for me or not?
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;
}
}
EDIT:
Here is ActivityMapping for Activity model.
public class ActivityMap : ClassMap<Activity>
{
public ActivityMap()
{
Id(x => x.Id);
Map(x => x.Type).CustomType(typeof(Int32));
References(x => x.User).Nullable();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您的问题是生成的 SQL 是什么样子,我的猜测是:
既然您提到 Activity 计数很大,您可以利用
ICriteria 的
SetFirstResult
和SetMaxResult
。SetFirstResult(int)
表示您希望获取的第一项的索引,SetMaxResult(int)
表示您希望获取的行数,在您的情况下为 25。ToList
会一次性加载内存中的所有记录。[UPDATE] 如果您需要一条一条地返回记录,请使用 Enumerable() -
如果您希望查询返回大量对象,但又不希望如果全部使用它们,您可能会从返回 System.Collections.IEnumerable 的 Enumerable() 方法获得更好的性能。迭代器将使用初始 SQL 查询返回的标识符按需加载对象(n+1 选择总计)。
来源 - 链接
If your question is about how the generated SQL would look like, my guess would be :
Since you have mentioned that the Activity count is huge, you can make use of
ICriteria's
SetFirstResult
andSetMaxResult
.SetFirstResult(int)
indicates the index of the first item that you wish to obtain andSetMaxResult(int)
indicates the number of rows you wish to get, 25 in your case.The
ToList
would load all the records in memory at once.[UPDATE] If you need the records to be returned one by one, make use of Enumerable() -
If you expect your query to return a very large number of objects, but you don't expect to use them all, you might get better performance from the Enumerable() methods, which return a System.Collections.IEnumerable. The iterator will load objects on demand, using the identifiers returned by an initial SQL query (n+1 selects total).
Source - Link
不,List() 方法将所有内容立即拉入内存。
No, the List() method pulls everything into memory at once.