c# - 如何在 NHibernate 中强制加载代理对象?

标签 c# sql-server nhibernate orm lazy-evaluation

我现在正在使用 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/

相关文章:

c# If else简写

mysql - 将三个表与 2 个不同的公共(public)列连接起来

sql-server - Go 无法从 MS SQL 2014 中读取最后一个 nvarchar(max) 值

c# - 如何在 HQL 中选择 bool 值?

c# - Entity Framework 与 Oracle 嵌套查询限制

c# - WPF如何将自己的对象暴露给其他窗口

Java 似乎截断了 MS-SQL 查询的长字符串结果

NHibernate AliasToBeanResultTransformer 和集合

c# - Windows Service增加CPU消耗

c# - 从数据库 SQLite C# 服务堆栈读取 SQL 数据(百万条记录)的最快方法是什么