В этом вопросе я спросил о времени жизни сессии NHibernate. Я использую настольное приложение, но с клиент-серверным разделением, таким образом, заключение состоит в том, что я буду использовать одну сессию на запрос к серверу, поскольку сторона сервера - то, где все волшебство NHibernate происходит.
Моя проблема теперь состоит в том, как обработать ее. У меня были проблемы прежде с загрузкой справочных данных, когда сеанс преждевременно закрыт. Проблема состоит в том, что я вижу следование моих классов, на которые ссылаются, при отладке - следовательно, справочные данные еще не загружаются:
основа {NHibernate. HibernateException} = {"Инициализирующий [MyNamespace. Foo#14] - не удалось лениво инициализировать набор роли: MyNamespace. Нечто. Панели, никакая сессия или сессия был закрыт"}
Из того, что я понимаю, что это не загружает все даже при том, что я фиксирую транзакцию. Таким образом, я узнал, что должен сохранить свою сессию открытой некоторое время, но сколько времени?
Мой вопрос состоит в основном в том, если я обрабатываю время жизни правильно, или что я должен изменить, чтобы быть на правильном пути. Честно я не вижу, как это может быть неправильно, поэтому что я действительно хотел бы, вызов функции гарантировать, что справочные данные выбираются. Я не использую ленивую загрузку, таким образом, я думал, что они будут сразу загружены..?
Текущая архитектура: Используя "сервисный класс" поведения, который делает транзакцию. Это - IDisposable, таким образом, сам сервис это с помощью пункта использования вокруг этого. NHibernateSessionFactory обеспечивает статическую фабрику, которая следовательно будет resused.
// This is the service - the function called "directly" through my WCF service.
public IList 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 SearchForFoo(string searchString)
{
using (var tx = _session.BeginTransaction())
{
var result = _session.CreateQuery("from Foo where Name=:name").SetString("name", searchString).List();
tx.Commit();
return result;
}
}
Оказывается, я все-таки делаю ленивую погрузку. У меня было следующее отображение:
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(); // <----------
}
}
Спасибо, что уделили мне время, и я все равно буду рад узнать ваше мнение о том, является ли данная мной структура разумной.
Если для сопоставления используются файлы xml, мы можем установить для пакета lazy = false.