2015-03-09 4 views
0

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

[The 'f.HIERARCHY.CHANGETIME = DateTime.Now;' линия внутри основного метода]

Я понимаю, что это происходит потому, что, когда NHibernate пытается принести «ИЕРАРХИЯ» объект сеанс уже закрыт внутри хранилища класса

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

Это хороший подход, чтобы всегда держать объект Isession открытым? Большинство образцов кода, которые я нашел в Интернете, всегда открывают новый сеанс для каждой операции CRUD для каждой операции и немедленно закрывают ее. Как они могут решить проблему доступа к свойствам навигации позже в коде?

public class NHibernateBaseRepository : IDisposable 
 
{ 
 

 
    private ISessionFactory m_SessionFactory = null; 
 
    private ISession m_Session = null; 
 

 
    public T GetById<T>(long id) 
 
\t \t { 
 
\t \t \t using (ISession session = m_SessionFactory.OpenSession()) 
 
\t \t \t { 
 
\t \t \t \t return session.Get<T>(id); 
 
\t \t \t } 
 
\t \t } 
 
} 
 

 
public class ROLE 
 
{ 
 
    public virtual string RoleComment { get; set; } 
 
    public virtual HIERARCHY HIERARCHY { get; set; } 
 
} 
 

 
public class HIERARCHY_STRUCTURE 
 
{ 
 
    public virtual DateTime CHANGETIME{ get; set; } 
 
} 
 

 
class Program 
 
{ 
 
    static void Main(string[] args) 
 
\t \t { 
 
\t \t \t NHibernateBaseRepository persistenceManager = new NHibernateBaseRepository(); 
 
\t \t \t ROLE f = persistenceManager.GetById<ROLE>(34); 
 

 
\t \t \t f.RoleComment = "Test Com"; 
 
\t \t \t f.HIERARCHY.CHANGETIME = DateTime.Now; //Throws error 
 
\t \t \t persistenceManager.SaveOrUpdateEntitiy<ROLE>(f); 
 
     } 
 
}

ответ

0

Как они решают вопрос о доступе к навигации свойства позже в коде?

без отключения отложенной загрузки

попытаться использовать Fetch() в хранилище, когда сеанс открыт. Например:

private IList<Container> ReadContainer() 
{ 
     var modeList = new List<Container>(); 

     using (var session = DatabaseHelper.OpenSession()) 
     { 
      var tmp = session.Query<Container>().Fetch(items => items.TmcList).ToList(); 
     } 
     return modeList; 
    } 
0

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

Это означает, что вам необходимо определить сеанс более глобальным образом, возможно, как частное поле в вашем классе NHibernateBaseRepository, создать экземпляр в конструкторе, а затем реализовать IDisposable и в методе Dispose закрыть сеанс. таким образом, вы можете выполнять несколько действий (и более последовательную часть работы) на одном сеансе.

Некоторые пример кода:

NHibernateBaseRepository класс:

public class NHibernateBaseRepository : IDisposable 
{ 
    private ISession _session; 

    public NHibernateBaseRepository() 
    { 
     _session = m_SessionFactory.OpenSession(); //session factory should be created once per application lifetime, not per instance. 
    } 

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

    public T GetById<T>(long id) 
    { 
     return _session.Get<T>(id); 
    } 
} 

Основной метод:

static void Main(string[] args) 
{ 
    using(var persistenceManager = new NHibernateBaseRepository()) 
    { 
     ROLE f = persistenceManager.GetById<ROLE>(34); 

     f.RoleComment = "Test Com"; 
     f.HIERARCHY.CHANGETIME = DateTime.Now; //Throws error 
     persistenceManager.SaveOrUpdateEntitiy<ROLE>(f); 
    } 
} 
Смежные вопросы