Пример реализации NHibernate TransactionService - PullRequest
0 голосов
/ 11 декабря 2011

Я получаю следующее сообщение при получении объектов моего домена:

failed to lazily initialize a collection of role no session or session was closed

Я знаю, что проблема связана с отложенной загрузкой коллекции на мой доменный объект, и я пытаюсь это исправить, но было бы неплохо, если бы кто-то мог указать мне правильное направление. Проблема в том, что у меня есть оператор using для моего объекта сеанса, и я хотел бы избавиться от сеансов в моих классах репозитория.

Stefan Steinegger рекомендует использовать TransactionService, который управляет транзакциями в следующем сообщении:

Было бы неплохо, чтобы кто-нибудь смог предоставить учебное пособие, например, о том, как реализовать такой сервис.

1 Ответ

1 голос
/ 11 декабря 2011

Существует несколько различных способов справиться с этим в веб-приложении, и , вероятно, , наиболее распространенным в веб-приложениях является сеанс на веб-запрос.

Внутри Application_Start в global.asax.cs создайте SessionFactory и назначьте его статическому свойству:

public static ISessionFactory SessionFactory { get; private set; }

protected void Application_Start(object sender, EventArgs e) 
{
    // your configuration setup
    var configuration = new NHibernate.Cfg.Configuration().Configure();
    SessionFactory = configuration.BuildSessionFactory();
}

Затем в Application_BeginRequest в global.asax.cs откройте сеанс с помощью SessionFactory и привяжите его к CurrentSessionContext

protected void Application_BeginRequest(object sender, EventArgs e)
{
    var session = SessionFactory.OpenSession();
    CurrentSessionContext.Bind(session);
}

и Application_EndRequest в global.asax.cs, отсоедините сеанс и избавьтесь от него

protected void Application_EndRequest(object sender, EventArgs e)
{
    var session = CurrentSessionContext.Unbind(SessionFactory);
    session.Dispose();
}

Теперь внутри приложения, когда требуется сеанс, мы просто запрашиваем SessionFactory текущий сеанс

public class HomeController : Controller
{
    public ActionResult Index()
    {
        IEnumerable<Product> products = null;
        var session = MvcApplication.SessionFactory.GetCurrentSession();
        using (var transaction = session.BeginTransaction())
        {
            // your query, which sounds like it should also eager load
            // a child collection
            products = session.QueryOver<Product>().List();
            transaction.Commit();
        }

        return View(products);
    }
}

Существует множество вариантов, включая использование LazySessionContext для ленивого создания сеанса, только если он необходим для запроса, и реализации, где ISessionFactory может быть введено в ваши контроллеры через зависимость инъекции.

...