C# 实体框架中的嵌套工作单元

C# 实体框架中的嵌套工作单元,c#,.net,entity-framework,nested,unit-of-work,C#,.net,Entity Framework,Nested,Unit Of Work,我尝试在应用程序中使用嵌套的工作单元来实现工作单元模式 我有以下接口: interface IDataService { IUnitOfWork NewUnitOfWork(); INestedUnitOfWork NewNestedUnitOfWork(IUnitOfWork parent); } interface IUnitOfWork : IDisposable { void Commit(); } interface INestedUnitOfWork : IUnitO

我尝试在应用程序中使用嵌套的工作单元来实现工作单元模式

我有以下接口:

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
}
这几乎就是世界上发生的事情

是否有机会使用实体框架(假设版本4)轻松实现这些接口


我使用的是自动生成的实体对象,而不是POCO。

不完全是您的方式,因为我使用的是带有状态标志的POCO,但它也可以应用于生成的实体。这是一种递归方法,用于管理父实体和子实体的状态。这是父实体的状态管理器类:

IStateManager是一个简单的接口,只有ChangeState方法。
如果子实体具有孙子集合,则ChildStateManager.SetRelationsState方法将调用孙子StateManager.ChangeState等。这有点复杂,但对我来说是可行的,我使用T4模板生成状态管理器代码

当您尝试使用实体框架做一些很酷的事情时,您将很难理解为什么要切换到Lightspeed。您需要查看EF工作单元的当前实现,并确定如何实现嵌套。这里有一些很棒的代码,我尝试了事务,但它们不会在回滚时还原对象上下文更改。所以,我仍然无法确定如何实现嵌套。@dradu:对不起,我看不出这对我的场景有什么帮助,例如:1在新创建的会话中选择某个父对象,2对其基本属性进行一些更新,3对具有取消功能的子对象进行一些更改,如有要求,4保存更改未取消抱歉没有太多帮助。我不确定嵌套工作单元的概念。通常,EF上下文实现一个工作单元接口。UoW被传递到一个或多个存储库,这些存储库对相应的实体执行更新。最后,如果发生任何错误,UoW提交更改或回滚所有内容。你说过,如果有人要求,可以对子对象进行一些更改,以取消这些更改,但这应该在什么时候发生?@dradu:想象一下,我在一个表单中编辑复杂对象。它具有子对象的集合。每个子对象都有其其他对象的子集合。我想以只读模式显示子记录,并以另一种形式编辑它们。我可以保存viewmodel中所有值的副本,但当嵌套级别超过2级时,它会变得非常复杂。要求能够取消任何级别的更改,包括在子级中所做的更改。我认为筑巢方法会对我有很大帮助。
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);
        }
    }
}
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)
    {
    }
}