2012-05-25 64 views
2

我有一個NHibernate存儲庫。我想在nhibernate會話中的加載和卸載對象上調用Update方法。Nhibernate更新和合並方法

但我有這個異常,這意味着我應該調用合併方法,而不是更新。 如何推廣我的存儲庫以避免此異常?

不同的對象具有相同標識符值已與會話相關聯:0adc76b1-7c61-4179-bb39-a05c0152f1a1,實體:Eshop.Entities.Currency

這裏是我的通用倉庫:

public class NHibernateProvider : IDataProvider 
{ 
    #region Variables 

    private readonly object locker = new object(); 
    private ISessionFactory sessionFactory; 
    private Configuration configuration; 
    private ITransaction transaction; 

    #endregion 

    #region Properties 

    private ISessionFactory SessionFactory 
    { 
     get 
     { 
      lock (locker) 
      { 
       if (Null.IsObjectNull(HttpContext.Current.Items["DataProvider"])) 
       { 
        configuration = new Configuration(); 

        configuration.Configure(); 

        HttpContext.Current.Items["DataProvider"] = sessionFactory = configuration.BuildSessionFactory(); 

        HttpContext.Current.Items["DataProviderSession"] = sessionFactory.OpenSession(); 
       } 


       return (HttpContext.Current.Items["DataProvider"] as ISessionFactory); 
      } 
     } 
    } 

    private ISession session; 
    private ISession Session 
    { 
     get 
     { 


      if (Null.IsObjectNull(HttpContext.Current.Items["DataProviderSession"])) 
      { 
       session = SessionFactory.OpenSession(); 

       session.FlushMode = FlushMode.Auto; 

       HttpContext.Current.Items["DataProviderSession"] = session; 
      } 
      else 
      { 
       session = HttpContext.Current.Items["DataProviderSession"] as ISession; 
      } 
      return session; 

     } 
    } 

    #endregion 

    #region Methods 


    public T Get<T>(Guid ID) 
    { 
     return Session.Get<T>(ID); 
    } 

    public T Get<T>(Expression<Func<T, bool>> predicate) 
    { 
     return Session.Query<T>().Where(predicate).FirstOrDefault(); 
    } 

    public IQueryable<T> GetAll<T>() 
    { 
     return Session.Query<T>(); 
    } 

    public IQueryable<T> GetAll<T>(Expression<Func<T, bool>> predicate) 
    { 
     return Session.Query<T>().Where(predicate); 
    } 

    public IQueryable<T> GetAll<T>(Expression<Func<T, bool>> predicate, int currentPage, int pageSize 
           ) 
    { 
     if (Session.Query<T>().Any(predicate)) 
     { 
      return Session.Query<T>().Where(predicate).Skip<T>(currentPage*pageSize).Take(pageSize); 
     } 
     return new List<T>().AsQueryable(); 
    } 

    public IQueryable<T> GetAll<T, TKey>(Expression<Func<T, bool>> predicate, int currentPage, int pageSize, 
             Expression<Func<T, TKey>> sortExpression) 
    { 
     if (Session.Query<T>().Any(predicate)) 
     { 
      return 
       Session.Query<T>().Where(predicate).Skip<T>(currentPage*pageSize).Take(pageSize).OrderBy<T, TKey>(
        sortExpression); 
     } 
     return new List<T>().AsQueryable(); 
    } 

    public bool Exists<T>(Guid ID) 
    { 
     if (Null.IsNotObjectNull(Session.Get<T>(ID))) 
     { 
      return true; 
     } 
     return false; 

    } 

    public bool Exists<T>(Expression<Func<T, bool>> predicate) 
    { 
     return Session.Query<T>().Where(predicate).Any(); 
    } 

    public void Update<T>(T targetObject, bool commit = true) where T:class 
    { 
     try 
     { 
      BeginTransaction(); 

      Session.Update(targetObject); 

      CommitTransaction(commit); 


     } 
     catch (Exception) 
     { 
      RollBackTransaction(); 
      throw; 
     } 
    } 

    public void Update<T>(IEnumerable<T> targetObjects, bool commit = true) where T : class 
    { 
     try 
     { 
      BeginTransaction(); 

      foreach (var target in targetObjects) 
      { 
       Session.Update(target); 
      } 

      CommitTransaction(commit); 


     } 
     catch (Exception) 
     { 
      RollBackTransaction(); 
      throw; 
     } 
    } 

    public void Insert<T>(T targetObject, bool commit = true) 
    { 
     try 
     { 
      BeginTransaction(); 

      Session.Save(targetObject); 
      CommitTransaction(commit); 

     } 
     catch (Exception) 
     { 
      RollBackTransaction(); 
      throw; 
     } 
    } 



    public void Insert<T>(IEnumerable<T> targetObject, bool commit = true) 
    { 
     foreach (T target in targetObject) 
     { 
      Insert<T>(target, false); 
     } 
     CommitTransaction(commit); 
    } 


    public void Delete<T>(T targetObject, bool commit = true) 
    { 
     try 
     { 
      BeginTransaction(); 

      Session.Delete(targetObject); 
      CommitTransaction(commit); 
     } 
     catch (Exception) 
     { 
      RollBackTransaction(); 
      throw; 
     } 
    } 

    public void Delete<T>(Guid targetID, bool commit = true) 
    { 
     try 
     { 
      BeginTransaction(); 

      Session.Delete(Get<T>(targetID)); 

      CommitTransaction(commit); 
     } 
     catch (Exception) 
     { 
      RollBackTransaction(); 
      throw; 
     } 
    } 


    public void Delete<T>(Expression<Func<T, bool>> predicate, bool commit = true) 
    { 
     try 
     { 
      BeginTransaction(); 
      if (Session.Query<T>().Any(predicate)) 
      { 
       foreach (T element in Session.Query<T>().Where(predicate)) 
       { 
        Session.Delete(element); 
       } 
      } 
      CommitTransaction(commit); 
     } 
     catch (Exception) 
     { 
      RollBackTransaction(); 
      throw; 
     } 
    } 

    private void RollBackTransaction() 
    { 
     transaction.Rollback(); 
    } 

    private void CommitTransaction(bool commit) 
    { 
     if (commit && transaction.IsActive) 
     { 
      transaction.Commit(); 
     } 
    } 


    private void BeginTransaction() 
    { 
     if (Session.Transaction.IsActive == false) 
     { 
      transaction =Session.BeginTransaction(); 
     } 
    } 

    #endregion 

} 

回答

2

發現我應該使用合併,因爲合併將決定在NHibernate會話中考慮它的狀態(分離,持久)來合併或更新實體。