NHibernate Unit Of Work - несколько сессий (WinForms)
Я борюсь с кривой обучения для NHibernate.
В настоящее время мы переносим наше приложение C# Winforms для использования NHibernate и используем Unit Of Work (UnitOfWork), как подробно описано Габриэлем Шенкером.
Мы хотим использовать Unit of Work на "Разговорной" основе. Например, когда пользователь открывает форму, мы открываем сеанс UnitOfWork и затем сохраняем его открытым, пока форма не будет закрыта. Формы - это просто более простой способ определения делового разговора, мы можем немного изменить это в зависимости от реализации, но для этого примера, пожалуйста, используйте открытие и закрытие формы в качестве примера.
Проблема существует, когда у нас есть сценарий открытия формы поверх другой формы. В этом случае у нас должно быть два работающих UnitOfWork. Один по-прежнему активен для базовой формы и новый UnitOfWork для новой формы.
Как мы это реализуем? Функциональность UnitOfWork, предоставляемая Габриэлем, допускает только один сеанс на UnitOfWork? Сначала я хочу сохранить сессии в Словаре, чтобы они могли вызываться из любой формы или части приложения.
Твои мысли?
3 ответа
Прочитайте статью Ayende "Создание настольного приложения с помощью NHibernate" в журнале MSDN здесь: http://msdn.microsoft.com/en-us/magazine/ee819139.aspx. Он обсуждает, как управлять несколькими единицами работы в толстом клиентском приложении.
Если вторая форма является дочерней формой - например, модальной формой для редактирования деталей - тогда она участвует в том же самом UOW, что и родительский, и UOW должен быть передан от родительского к дочернему, обычно в конструкторе.
Я не фанат подхода в статье Габриэля Шенкера; Я думаю, что лучше использовать ISession напрямую как реализацию UOW.
Статья Айенде, на которую есть ссылка в ответе Джеймса, хороша, но мы делаем это немного по-другому. Для форм верхнего уровня, которые управляют своим собственным UOW, у нас есть статический метод в Program.cs для создания ISession, который вызывается в конструкторе формы:
private readonly ISession _session;
public frmPlayerViewer()
{
InitializeComponent();
// bail out if we're in the designer
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
{
return;
}
_session = Program.OpenEvtSession(FlushMode.Commit);
}
Чтобы убедиться, что ISession правильно расположен, переопределите OnFormClosing:
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
if (!e.Cancel && _session != null)
{
if (_session.Transaction.IsActive)
{
const string msg = "OnFormClosing with active transaction.";
log.Error(msg);
throw new Exception(msg);
}
_session.Dispose();
}
}
Этот код находится в базовой форме, которую расширяют формы верхнего уровня.
Я только что реализовал , которая устраняет две самые неприятные проблемы NHibernate: прокси-классы и декартово произведение при использовании выборки.единицу работы для NHibernate под названием NHUnitNHUnit отделяет ваш код от реализации ORM. Это означает, что вы можете переключиться на другой ORM, просто реализовав два интерфейса:
IUnit
а также
IRepository
. На Github есть простой пример проекта , показывающий, как использовать пакет NHUnit .