2009-09-21 95 views
2

我想在使用DDD方法的ASP.NET MVC应用程序中设置NHibernate。但是,在尝试延迟加载与对象相关的实体时确实发生错误。继承人我是如何构建我的应用程序:NHibernate:“未能懒惰地初始化...”,DDD方法

基础设施层: 包含映射文件,资料库的实现和NHibernate的引导程序来配置和建立一个会话工厂。

下面有一个存储库例如:

public class CustomerRepository : ICustomerRepository 
{ 
    public Customer GetCustomerById(int customerId) 
    { 
     using (var session = NHibernateBootstrapper.OpenSession()) 
      return session.Get<Customer>(customerId); 
    } 
} 

域层: 简单POCO类,库和服务接口

应用层: 包含服务实现。

下面有一个服务例如:

public class CustomerService : ICustomerService 
{ 
    private ICustomerRepository _repository; 

    public CustomerService(ICustomerRepository repository) 
    { 
     _repository = repository; 
    } 

    public Customer GetCustomerById(int customerId) 
    { 
     return _repository.GetCustomerById(customerId); 
    } 
} 

表示层: 包含ASP.NET MVC应用程序。这是我发现我的问题的地方。 使用MVC方法,我有一个控制器,使用CustomerService服务获取客户并在View中显示客户(强类型)。这个客户有一个相关的实体联系人,当我尝试在View中使用Model.Contact访问它时,其中Model是我的Customer对象,我得到一个LazyInitializationException。

我知道我为什么得到这个。这是因为用于检索CustomerRepository中的Customer的会话现在已经失效。我的问题是我如何解决这个问题。我想如果我可以避免在我的存储库中获取客户的相关联系人实体,因为某些视图只需要客户数据,而不需要联系人数据。如果这是可能的话?

所以对于这个问题:是否有可能等待查询数据库,直到表示层需要相关实体Contact?

我认为我需要的是类似于article所描述的内容。我只是不知道如何在基础设施层实现它,或者它应该在哪里实现?

在此先感谢。任何帮助都感激不尽!

回答

2

至于会话管理,通常每个请求使用单个会话。你可以看到一个实施例here。这是一个开源项目,旨在借助Nhibernate轻松设置新的asp.net应用程序。源代码可以创建为here

希望它有帮助。

0

是否在您的客户类中标记为virtual的所有属性和方法?

你打开和关闭你的会议?我用ActionFilterAttribute调用TransactionPerRequest并用它装饰我的所有控制器。

检出this的实现。

1

我还推荐Sharp Architecture。

另一种方法以及建议是避免将实体传递给视图。除了会话管理外,还有其他一些问题 - 业务规则泄漏到视图中,在那里膨胀/分割代码等。使用ViewModel方法。

您将遇到的另一个问题是将您的实体存储在Session中。一旦您尝试从Session [“customer”]获得您的客户,您将得到相同的例外。有几种解决方案,例如存储ID或添加存储库方法以防止您将要在会话中存储的对象的延迟加载 - 读取NHibernate的SetFetchMode - 当然,您也可以使用它将实体传递给观点。但正如我所说,你最好坚持使用ViewModel方法。 Google for ViewModel,或者参考使用http://code.google.com/p/codecampserver/代码示例的ASP.NET MVC In Action书。例如,还读取this

相关问题