2012-03-13 91 views
1

我正嘗試使用會話每請求模式,並且在保存後立即獲取記錄時遇到問題。這樣做的原因是我需要獲取外鍵相關的記錄。NHibernate Session/Transaction Woes

一些(簡化)代碼:

// UnitOfWork Attribute 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     SessionFactory.Begin(); 
    } 

    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     if (filterContext.Exception == null) { 
      try { 
       SessionFactory.Commit(); 
      } catch { 
       SessionFactory.Rollback(); 
       throw; 
      } 
     } else { 
      SessionFactory.Rollback(); 
      throw filterContext.Exception; 
     } 
    } 

    // Service layer 

    public void Save(Form form) 
    { 
     _repository.Save(form); 

     var savedForm = _repository.Get(form.Id); 
     SendEmail(savedForm); 
    } 

    // Repository 

    public void Save(Form form) 
    { 
     var session = SessionFactory.CurrentSession; 

     session.SaveOrUpdate(form); 
    } 

的問題是,當我試圖讓記錄,交易尚未提交,因此它只是給我什麼已經在會話。我只需要在保存後提交交易,並打開一個新交易以獲取它?

感謝

更新:

我實現了做事的Agathas店面的方式,從而實現業務層的控制權交易,即:

public class UnitOfWork : IUnitOfWork 
{ 
    public void Commit() 
    { 
     var session = SessionFactory.CurrentSession; 

     using (ITransaction transaction = session.BeginTransaction()) 
     { 
      try { 
       transaction.Commit(); 
      } catch { 
       transaction.Rollback(); 
       throw; 
      } 
     } 
    } 


    public void Clear() 
    { 
     var session = SessionFactory.CurrentSession; 

     session.Clear(); 
    } 
} 

然後服務層:

public void SaveForm(Form form) 
{ 
    _repository.Save(form); 

    _uow.Commit(); 
    _uow.Clear(); 

    var savedForm = _repository.Get(form.Id); 
    SendEmail(savedForm); 
} 

更新2

好吧,我想我找到了一個合適的解決方案。我已經回到了每次請求事務模式,並且在保存表單之後,我現在正在刷新它,然後從會話中清除表單,以便強制NH從數據庫中獲取它。

// Service layer 
public void SaveForm(Form form) 
{ 
    _repository.Save(form); 

    var savedForm = _repository.Get(form.Id); 
    SendEmail(savedForm); 
} 

// Repository 

public void Save(Form form) 
{ 
    var session = SessionFactory.CurrentSession; 

    session.SaveOrUpdate(form); 
    session.Flush(); 
    session.Evict(form); 
} 
+0

您是否是列ID的標識列? – Rippo 2012-03-13 19:52:35

+0

我是,但那不是我的主要問題(儘管它仍然是一個問題)。我的主要問題是無法加載外鍵記錄。也許懶加載會處理這個問題呢? – Tom 2012-03-14 11:01:45

+0

這是你的問題,身份是你的敵人,尤其是當你使用一個單位的工作。如果實體尚未首先發送到數據庫,該實體如何獲取其ID? – Rippo 2012-03-14 17:16:47

回答

1

在您刷新會話或減少事務範圍之前,您將不會擁有一個ID,因爲nhibernate不會插入該記錄。

+0

謝謝。 session.Refresh()似乎不起作用,雖然session.Clear()會。我最終通過對事務進行服務層控制而不是每個請求的事務來改變工作單元模式,就像Agathas店面項目一樣。 – Tom 2012-03-14 10:47:24

+0

如果您自己分配ID(hilo或guid對此很好,已經有算法),您可以爲每個請求進行交易。 – Fourth 2012-03-14 12:49:32

+0

問題是,這是一個我正在轉換到NHibernate的項目,所以我真的不想開始搞亂已經在數據庫中的ID。 – Tom 2012-03-14 12:56:49