在使用.Fetch
但是,一旦我有一个加载的实体 - 一个空的集合(因为我选择不在查询时因为笛卡尔积的副作用而急于加载),我可以选择稍后加载一个集合,比如说在我完成了一些分页后,我有一个具体的项目列表?
类似的东西:
var list = (some linq over Session.Query<Entity>)
.Take(10).Skip(2)
.Fetch(x => x.MyCollection)
.ToList();
Session.Fetch<Entity>(list, l => l.OtherCollection);
修改 关键是 - 我已经在查询中获取了2个子集合 - 使得查询和结果集已经相当大(参见nhibernate Cartesian产品)。我想分页结果,获取10的列表然后可选地返回数据库以填充分页(10,比方说)结果的子集合属性。这是性能考虑因素。
答案 0 :(得分:1)
发出此查询
/*we dont need the result*/Session.QueryOver<Entity>()
.Where(x => x.Id.IsIn(list.Select(l => l.Id)))
.Fetch(l => l.OtherCollection)
.ToList();
然后nhibernate应该初始化实体上的集合
编辑:
改善初始加载时间,请参阅http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate
那么你可以做exmaple
var results = (some linq over Session.Query<Entity>)
.Take(10).Skip(2)
.ToList();
var q = Session.QueryOver<Entity>()
.Where(x => x.Id.IsIn(list.Select(l => l.Id)))
.Fetch(l => l.MyCollection)
.ToFuture();
Session.QueryOver<Entity>()
.Where(x => x.Id.IsIn(list.Select(l => l.Id)))
.Fetch(l => l.OtherCollection)
.ToFuture();
Session.QueryOver<Entity>()
.Where(x => x.Id.IsIn(list.Select(l => l.Id)))
.Fetch(l => l.ThirdCollection)
.ToFuture();
return q.ToList()
答案 1 :(得分:0)
我刚刚开始阅读有关NHibernate中的期货和预测的内容,这看起来很有希望作为解决方案...当我发现它时会发布更多内容。
这是一个解决方案:http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate,但我仍然不喜欢它,因为我的查询本身非常昂贵(使用'%like%@ + paging),所以执行3或4次只是为了加载集合看起来很贵
修改强>
这就是我所拥有的。查看生成的sql,正在运行正确的sql并返回预期结果,但返回结果的集合为null。你能看到缺少的东西吗?:
public List<Company> CompaniesForLoggedInUser(int pageSize, int pageNumber)
{
var list =
QueryForCompaniesFor(SecurityHelper.LoggedInUsername)
.Page(pageNumber, pageSize)
.ToList()
.FetchCompanyCollections(Session);
return list;
}
internal static class CompanyListExtensions
{
internal static List<Company> FetchCompanyCollections(this List<Company> companies, ISession session)
{
var ids = companies.Select(l => l.Id).ToArray();
session.QueryOver<Company>()
.Where(x => x.Id.IsIn(ids))
.Fetch(l => l.Properties).Eager()
.Future();
return session.QueryOver<Company>()
.Where(x => x.Id.IsIn(ids))
.Fetch(l => l.UserAccessList).Eager()
.Future()
.ToList();
}
}