我现在正在使用 NHibernate,并且遇到了一个问题,试图提高我正在处理的数据带宽效率。
上下文是我正在制作一个数据事件编辑器,它有一个填充了事件的 ListView 。这些事件有 3 种类型,每种都存储在自己的 MSSQL 表中。
有一个父对象,其中包含这 3 种事件类型的列表。最初,我只是选择所有 parent 并加载其下的事件,但如果您说有 20 个 parent ,那么它将运行 60 次左右的查询来加载列表。
我现在将其更改为仅运行 3 个查询,其中一个用于选择日期 X 和日期 Y 之间的所有事件类型。(此日期是使用表单上的一些日期时间选择器设置的)。
现在,我也试图在列表中打印父级的名称,但是因为我在 nHibernate 期间从未访问过父级,所以我只有一个“代理”对象,它会导致崩溃。 Parent 对象下可能有数千个不同的对象,所以我只想加载我需要的。
在此期间,为了让它能够编译,我所做的是在我的 nHibernate 期间访问该对象。
我获取事件的代码如下:
public IList<MyEvent> GetAllMyEventForAllParentsFromSpecificTimePeriod(
DateTime startTime, DateTime endTime)
{
using (var session = SessionFactorySingleton.OpenSession())
{
var queryOver = session
.QueryOver<MyEvent>()
.Where(re => re.Time <= endTime)
.And(re => startTime <= re.Time)
.OrderBy(re => re.Time).Desc;
var list = queryOver.List();
if (list.Count > 0)
{
foreach (var myEvent in list.Select(myEvent => myEvent.ParentItem.Name)) { }
}
return list;
}
}
到目前为止,我发现列表以这种方式加载得更快。
所以我想这里真正的问题是我可以做些什么来实现与我访问每个 ParentItem.Name 的位置相同的东西,只是为了强制它加载它们?
更新后的答案: 多亏了一位同事,我成功地提高了效率。
return session
.QueryOver<MyEvent>()
.Where(re => re.Time <= endTime)
.And(re => startTime <= re.Time)
.JoinQueryOver(x => x.ParentItem)
.List();
答案:
foreach (var parent in list.Select(x => x.ParentItem)) { NHibernateUtil.Initialize(parent); }
相当于:
public IList<MyEvent> GetAllMyEventForAllParentsFromSpecificTimePeriod(
DateTime startTime, DateTime endTime)
{
using (var session = SessionFactorySingleton.OpenSession())
{
var list = session
.QueryOver<MyEvent>()
.Where(re => re.Time <= endTime)
.And(re => startTime <= re.Time)
.List();
foreach (var parent in list.Select(x => x.ParentItem)) { NHibernateUtil.Initialize(parent); }
return list;
}
}
最佳答案
如果您只是所有 ParentItem 名称,您可以使用一个选择。
var queryOver = session.QueryOver<Parent>()
.Select(p => p.Name))
.List<string>()
关于c# - 如何在 NHibernate 中强制加载代理对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32834494/