首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我在我的第一个(fluent) nhibernate查询Initializing[type]-failed中出错.没有会议或会议闭幕

我在我的第一个(fluent) nhibernate查询Initializing[type]-failed中出错.没有会议或会议闭幕
EN

Stack Overflow用户
提问于 2010-10-31 08:07:48
回答 1查看 1.4K关注 0票数 3

我刚从NHibernate开始,使用fluent NHibernate创建了映射,如下所示:

代码语言:javascript
复制
public class CustomerMap : ClassMap<Customer>
{
    public CustomerMap()
    {
        Id(x => x._id, "Id");
        Map(x => x._KdNr, "KdNr");
        Map(x => x._Name, "Name");
        HasMany(x => x._Contact)
            .Table("Contacts")
            .KeyColumn("FKCustomerID")
            .LazyLoad();
    }
}


public class ContactMap : ClassMap<Contact>
{
    public ContactMap()
    {
        Id(x => x._id, "Id");
        Map(x => x._Name, "Name");
    }
}

保存新记录的工作还包括:

代码语言:javascript
复制
    public static void AddCustomer(Customer cust)
    {
        using (var session = SessionFactory.Instance.OpenSession())
        {
            session.Save(cust);
            session.Save(cust._Contact);
            session.Flush();
        }
    }

然后,我尝试使用以下方法选择添加的客户:

代码语言:javascript
复制
        using (var session = SessionFactory.Instance.OpenSession())
        {
            try
            {
                var v = session.CreateQuery("from Customer").List<Customers>();
                return (List<Customer>)v;
            }
            catch
            {
                session.Close();
                throw;
            }
            finally
            {
                session.Disconnect();
            }
        }
    }

客户也可以很好地加载,但是内部的联系人没有引用以下错误:

Initializingfnh.DataModel.Customer#d2f2d1c5-7d9e-4f77-8b4f-9e200088187b-failed延迟初始化角色集合: fnh.DataModel.Kunde._Contact,没有关闭任何会话或会话

但是我不明白错误是从哪里来的,因为会话在执行HQL错误后关闭了.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-10-31 16:05:33

问题是这些联系人装得很懒。在初始查询中,集合不会从数据库中获取。我假设您是直接将对象传递到视图,而不是使用视图模型吗?你有几个选择,每个选项都有它们的缺点。

  1. 在视图正在处理时保持会话打开(所谓的“视图中的开放会话”方法)。你现在很可能会在控制器上关闭NH会话,对吧?
  2. 在联系人上使用.Not.Lazyload()加载整个对象图。(不建议)
  3. 将所需的所有数据复制到控制器中的视图模型中,并将其传递给视图。使用automapper来帮助您完成这一任务。

更新回应评论:

让集合延迟加载仍然有很大的好处。当然,在这种情况下,您不会从客户对象上延迟加载的联系人中获益,因为您需要使用它们。但在另一种情况下,您可能只需要客户名称和Id -您可以放心,这不会产生一个大查询与联接等。

要利用视图中的Open,您不必显式地将会话传递给视图,而是像以前一样传递对象,但让会话保持打开状态-- NH将在尝试访问联系人集合时自动生成新的查询。(这是因为customer对象仍然“连接”在幕后的开放会话)。这里唯一的区别是,您需要关闭会话,而不是在控制器中(在控制器中,它目前正显式地使用.close()关闭,或者隐式地使用‘The’)。关于会议在何处开幕和闭幕的问题,有几种不同的做法:

  • 在global.asax - open Application_BeginRequest和close In Application_EndRequest (请参阅:这篇文章)中,为了简单起见,如果您想在视图中执行开放会话,请从这里开始。
  • 在http模块中(基本上与最后一个模块相同,但模块化)(请参见这篇文章)

对于最后两个页面,您可能会想‘但这将意味着为每个页面请求创建一个会话!’--您是对的,但是到底有多少页不会转到DB呢?此外,一旦创建了会话工厂,会话创建也是轻量级的。

  • 使用属性修饰操作方法(基本上与最后两个操作相同,但这样可以选择打开NH会话的操作)。如果要在操作完成后关闭会话,请在OnActionExecuted中关闭它。如果希望在视图中打开会话,请在OnResultExecuted中关闭。

当然,许多人不喜欢视图中的开放会话,因为您无法控制纯粹在控制器中生成哪些查询--视图触发了许多查询,这会导致无法预测的性能。

3与2有很大的不同,因为在不需要延迟加载的集合的情况下,它不会从DB中获取。例如,在本例中,您可能使用完整的对象图复制到ViewModel,但在另一种情况下,您可能使用只具有客户名称和Id的ViewModel --在本例中,联系人集合的联接不会被不必要地执行。在我看来,3是正确的做事方式--但你最终会创建更多的对象(因为视图对象)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4062305

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档