实体框架中的嵌套工作单元 [英] Nested Unit of Work in Entity Framework

查看:52
本文介绍了实体框架中的嵌套工作单元的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I try to implement Unit of Work pattern in my application with use of nested units of work.

我有以下界面:

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 中发生的情况.

This is almost how things happen in XPO.

是否有可能使用Entity Framework(假设第4版)轻松实现这些接口?

Is there any chance to implement these interfaces using Entity Framework, suppose version 4, with little pain?

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

I use auto-generated entity objects, not POCO.

推荐答案

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

Not exactly your way, because I'm using POCO with state flags, but it can be applied to generated entities as well. This is a recursive approach to manage the state of the parent entity and children entities. This is the state manager class for the Parent entity:

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 实体的状态管理器:

And this is the state manager for the Child entity:

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模板生成状态管理器代码.

IStateManager is a simple interface which only has ChangeState method. If the Child entity had a GrandChild collection, the ChildStateManager.SetRelationsState() method would call the GrandChildStateManager.ChangeState() and so on. It's a bit complicated, but it works for me and I generate the state manager code using T4 templates.

这篇关于实体框架中的嵌套工作单元的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆