2009-09-21 4 views
2

Я пытаюсь настроить NHibernate в приложении ASP.NET MVC с использованием DDD-подхода. Тем не менее, я получаю сообщение об ошибке при попытке ленивой загрузки объекта, связанного с объектами. Вот как я структурирован мое заявление:NHibernate: «не удалось лениво инициализировать ...», подход DDD

Infrastructure слой: Содержит картографические файлы, реализацию хранилища и загрузчик NHibernate для настройки и создания сеанса завода.

Heres пример репозитория:

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

домена слой: Имеет простые классы POCO, хранилища и сервисные интерфейсы уровня

Применение: содержит реализации услуг.

Heres пример службы:

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, получает клиента и отображает клиента в представлении (строго типизированном). У этого клиента есть связанный с ним контакт, и когда я пытаюсь получить доступ к нему в моем представлении с помощью Model.Contact, где Model является объектом моего клиента, я получаю исключение LazyInitializationException.

Я знаю, почему я это понимаю. Это связано с тем, что сеанс, используемый для извлечения Клиента в CustomerRepository, уже мертв. Моя проблема в том, как я могу это исправить. Я хотел бы, если бы я мог избежать получения связанного объекта Contact для Клиента в моем репозитории, потому что некоторым представлениям нужны только данные Клиента, а не данные Contact. Если это вообще возможно?

На вопрос: можно ли дождаться запроса в базе данных до тех пор, пока уровень представления не потребует связанного с ним объекта связи?

Я думаю, что мне нужно что-то вроде того, что описывает этот article. Я просто не могу понять, как реализовать его на уровне инфраструктуры, или где он должен быть реализован?

Заранее спасибо. Любая помощь будет высоко ценится!

ответ

2

Что касается управления сеансом, то обычно используется один сеанс для каждого запроса. Вы можете увидеть пример реализации here. Это проект с открытым исходным кодом, который был разработан для установки новых приложений asp.net с помощью Nhibernate легко. исходный код может быть основан here.

Надеюсь, это поможет.

0

Все ли ваши свойства и методы в вашем классе клиентов отмечены как virtual?

Как вы открываете и закрываете сеанс? Я использую ActionFilterAttribute под названием TransactionPerRequest и украшаю все мои контроллеры.

Отъезд this для реализации.

1

Я также рекомендую Sharp Architecture.

Другой подход, а также предложение - избегать передачи объектов в представления. Есть и другие проблемы с ним, кроме управления сеансом - деловые правила протекают в виде, раздутом/spagetti-коде и т. Д. Используйте подход ViewModel.

Другая проблема, которую вы получите, заключается в хранении ваших объектов в сеансе. Как только вы попытаетесь получить своего клиента с сеанса [«клиент»], вы получите то же исключение. Для этого существует несколько решений, например, сохранение идентификаторов или добавление методов репозитория для предотвращения ленивой загрузки объектов, которые вы собираетесь хранить в сеансе, - прочитайте «SetFetchMode» NHibernate, который, конечно же, можно использовать для передачи объекта в Просмотры. Но, как я сказал, лучше придерживаться подхода ViewModel. Google для ViewModel или обратитесь к книге ASP.NET MVC In Action, в которой используются образцы кода от http://code.google.com/p/codecampserver/. Также читайте, например, this.

Смежные вопросы