Как управлять временем жизни NHibernate с помощью сервисов? - PullRequest
7 голосов
/ 08 января 2010

В этот вопрос Я задал вопрос о времени жизни сеанса NHibernate. Я использую настольное приложение, но с разделением клиент / сервер, поэтому вывод состоит в том, что я буду использовать один сеанс на каждый запрос к серверу, поскольку на стороне сервера происходит вся магия NHibernate.

Моя проблема сейчас в том, как справиться с этим. У меня были проблемы до с загрузкой ссылочных данных, когда сессия преждевременно закрыта. Проблема в том, что при отладке я вижу следующее в ссылочных классах, поэтому ссылочные данные еще не загружены:

base {NHibernate.HibernateException} = {"Initializing [MyNamespace.Foo # 14] - не удалось лениво инициализировать коллекцию ролей: MyNamespace.Foo.Bars, ни один сеанс или сеанс не был закрыт»}

Из того, что я понимаю, он не загружает все, даже если я совершаю транзакцию. Итак, я узнал, что мне нужно некоторое время держать сеанс открытым, но как долго?

Мой вопрос в основном заключается в том, правильно ли я отношусь к жизни, или что я должен изменить, чтобы быть на правильном пути. Честно говоря, я не понимаю, как это может быть неправильно, поэтому мне бы очень хотелось, чтобы был вызов функции, обеспечивающий выборку ссылочных данных. Я не использую ленивую загрузку, поэтому я думал, что они будут загружены немедленно ..?

Текущая архитектура: использование класса «поведение службы», которое выполняет транзакцию. Это IDisposable, поэтому сама служба использует условие использования вокруг него. NHibernateSessionFactory предоставляет статическую фабрику, которая, следовательно, будет использоваться повторно.

// This is the service - the function called "directly" through my WCF service. 
public IList<Foo> SearchForFoo(string searchString)
{
    using (var serviceBehavior = new FooServiceBehavior(new NhibernateSessionFactory()))
    {
        return serviceBehavior.SearchForFoo(searchString);    
    }                        
}

public class FooServiceBehavior : IDisposable
{
    private readonly ISession _session;

    public FooServiceBehavior(INhibernateSessionFactory sessionFactory)
    {
        _session = sessionFactory.OpenSession();                
    }

    public void Dispose()
    {
        _session.Dispose();
    }

    public IList<Foo> SearchForFoo(string searchString)
    {           
        using (var tx = _session.BeginTransaction())
        {
            var result = _session.CreateQuery("from Foo where Name=:name").SetString("name", searchString).List<Name>();
            tx.Commit();
            return result; 
        }
    }

Ответы [ 2 ]

5 голосов
/ 08 января 2010

Оказывается, я в конце концов делаю ленивую загрузку. У меня было следующее отображение:

public class FooMapping : ClassMap<Foo>
{
    public FooMapping()
    {
        Not.LazyLoad();
        Id(c => c.Id).GeneratedBy.HiLo("1");
        Map(c => c.Name).Not.Nullable().Length(100);
        HasMany(x => x.Bars).Cascade.All();
    }
}

Я предположил, что Not.LazyLoad() отключена отложенная загрузка, но, видимо, не для ссылочных объектов. Я добавил ленивую загрузку в ссылку, и это, похоже, решило проблему.

public class FooMapping : ClassMap<Foo>
{
    public FooMapping()
    {
        Not.LazyLoad();
        Id(c => c.Id).GeneratedBy.HiLo("1");
        Map(c => c.Name).Not.Nullable().Length(100);
        HasMany(x => x.Bars).Not.LazyLoad(); // <----------
    }
}

Спасибо за ваше время, и я все равно буду рад узнать ваше мнение о том, является ли моя структура разумной.

0 голосов
/ 26 февраля 2010

Если xml-файлы используются для сопоставления, мы можем установить lazy = false для пакета.

...