2012-05-20 50 views
1

我嘗試使用嵌套工作單元在我的應用程序中實現工作單元模式。實體框架中的嵌套工作單元

我有以下接口:

interface IDataService 
{ 
    IUnitOfWork NewUnitOfWork(); 
    INestedUnitOfWork NewNestedUnitOfWork(IUnitOfWork parent); 
} 

interface IUnitOfWork : IDisposable 
{ 
    void Commit(); 
} 

interface INestedUnitOfWork : IUnitOfWork 
{ 
    IUnitOfWork Parent { get; } 
    object GetParentObject(object obj); // get the same object in parent uow 
    object GetNestedObject(object obj); // get the same object in this uow 
} 

這幾乎是事情XPO是如何發生的。

有沒有機會使用實體框架實現這些接口,假設版本4,幾乎沒有什麼痛苦?

我使用自動生成的實體對象,而不是POCO。

+1

當您嘗試做實體框架很酷的事情,你將有一個壞的時間(爲什麼切換到光速)。您需要查看EF的當前工作單元並確定如何實現嵌套。一些偉大的代碼在這裏http://code.google.com/p/ef4prs/source/browse/trunk/Infrastructure.Data.EntityFramework/UnitOfWork.cs – Jeremy

+0

嗯,我想交易,但他們不恢復回滾對象環境的變化。所以,我仍然無法確定如何實現嵌套。 –

回答

0

不完全是你的方式,因爲我使用帶有狀態標誌的POCO,但它也可以應用於生成的實體。這是一種管理父實體和子實體狀態的遞歸方法。這是Parent實體狀態管理器類:

public partial class ParentStateManager : IStateManager<Parent, MyObjContext> 
{ 

    private IStateManager<Child, MyObjContext> _ChildStateManager = new ChildStateManager(); 
    public void ChangeState(Parent m, MyObjContext ctx) 
    { 
     if (m == null) return; 
     ctx.Parents.Attach(m); 
     if (m.IsDeleted) 
     { 
      ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Deleted); 
     } 
     else 
     { 
      if (m.IsNew) 
      { 
       ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Added); 
      } 
      else 
      { 
       if (m.IsDirty) 
       { 
        ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Modified); 
       } 
      } 
     } 
     SetRelationsState(m, ctx); 
    } 
    private void SetRelationsState(Parent m, MyObjContext ctx) 
    { 
     foreach (Child varChild in m.Children.Where(p => !p.IsDeleted)) 
     { 
      _ChildStateManager.ChangeState(varChild, ctx); 
     } 
     while (m.Children.Where(p => p.IsDeleted).Any()) 
     { 
      _ChildStateManager.ChangeState(m.Children.Where(p => p.IsDeleted).LastOrDefault(), ctx); 
     } 
    } 
} 

這是爲Child實體狀態管理:

public partial class ChildStateManager : IStateManager<Child, MyObjContext> 
{ 

    public void ChangeState(Child m, MyObjContext ctx) 
    { 
     if (m == null) return; 
     ctx.Children.Attach(m); 
     if (m.IsDeleted) 
     { 
      ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Deleted); 
     } 
     else 
     { 
      if (m.IsNew) 
      { 
       ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Added); 
      } 
      else 
      { 
       if (m.IsDirty) 
       { 
        ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Modified); 
       } 
      } 
     } 
     SetRelationsState(m, ctx); 
    } 
    private void SetRelationsState(Child m, MyObjContext ctx) 
    { 
    } 
} 

IStateManager是一個簡單的接口,它只有ChangeState方法。 如果Child實體具有GrandChild集合,則ChildStateManager.SetRelationsState()方法將調用GrandChildStateManager.ChangeState()依此類推。這有點複雜,但它適用於我,我使用T4模板生成狀態管理器代碼。

+1

不錯的做法@dradu – Jeremy

+0

@dradu:對不起,我不明白這是怎麼幫助我的,例如: 1)在新創建的會話中選擇一些'Parent'對象, 2)它的原始屬性, 3)對孩子**進行一些更改,並具有取消他們的能力**,如果要求的話 4)保存更改(未取消) –

+0

對不起,沒有太大的幫助。我不確定這個嵌套工作單元的概念。通常你的EF上下文實現一個工作單元界面。 UoW被傳遞給一個或多個存儲庫,這些存儲庫執行對相應實體的更新。最後,如果發生任何錯誤,UoW提交更改或回滾所有內容。你說過「如果有要求,對有能力取消他們的孩子進行一些更改」,但是什麼時候會發生? –