1

我有一个绑定到 NewUserViewModel 的视图,该视图已发布到控制器的此方法。

    [HttpPost]
    public ActionResult NewUser(NewUserViewModel newUser)
    {
        var user = new User();
        user.Id = newUser.Id;
        user.Email = newUser.Email;
        //more mapping hidden for brevity

        //here is where the trouble starts
        _userService.AddNewUser(user);

        return RedirectToAction("Users");
    }

_userService 位于一个私有字段中,该字段在控制器构造函数中实例化,如下所示

    private IUserService _userService;

    public ControllerName()
    {
        _userService = new UserService();
    }

_userService 上的 AddNewUser 方法如下所示。

        public void AddNewUser(User newUser)
        {
        using (var uow = new UnitOfWorkUser(new Context()))
        {
            using (var _userRepo = new UserRepository(uow))
            {
                _userRepo.InsertOrUpdate(newUser);
                uow.Save();
            }
        }
    }

UserRepository 的构造函数如下所示。

    private Context _context;

    public UserRepository(UnitOfWorkUser unitOfWork)
    {
        _context = unitOfWork.Context;
    }

而unitOfWork看起来像这样。

    public class UnitOfWorkUser :IDisposable, IUnitOfWork
{
    private readonly Context _context;

    public UnitOfWorkUser(Context context = null)
    {
       _context = context ?? new Context();
    }

    public int Save()
    {
        return _context.SaveChanges();
    }

    internal Context Context
    {
        get { return _context; }
    }

    public void Dispose()
    {
        _context.Dispose();
    }
}

_userRepo 上的 InsertOrUpdate 方法看起来像这样。

 public virtual void InsertOrUpdate(User user)
    {
        if (user.Id == default(int))
        {
            _context.Users.Add(user);
        }
        else
        {
            _context.Entry(user).State = System.Data.EntityState.Modified;
        }
    }

当我到达 _context.Users.Add(user); 在上面的方法中我得到这个错误

一个实体对象不能被多个 IEntityChangeTracker 实例引用。

我认为通过在 UserRepository 的构造函数中传递带有 UnitOfWork 对象的上下文,我将避免这些错误。

我究竟做错了什么?

4

2 回答 2

0

This looks very wrong to me. The purpose of unit work pattern is to consolidate all your "work" in one object. There is several issue with the following code:

  1. Looks like you are disposing the DBContext Twice

  2. Since you only need dbcontext, you shouldn't only pass dbcontext to the repository instead of UOW object

  3. You might want to have a internal reference to the UserRepository. It should be used to group your Repositories and ensure they all share the same EF context instance. A sample will look like UnitOfWorkUser.UserRepo.Save(newUser)

        using (var uow = new UnitOfWorkUser(new Context()))
        {
            using (var _userRepo = new UserRepository(uow))
            {
                _userRepo.InsertOrUpdate(newUser);
                uow.Save();
            }
        }
    

Here is an example on how you use UOW,

http://www.mattdurrant.com/ef-code-first-with-the-repository-and-unit-of-work-patterns/

于 2012-12-05T01:38:01.013 回答
0

在 asp.net mvc 中使用 UOW 有更好的方法,你不会在上下文中考虑实体生命周期的许多方面,所以我建议阅读这篇文章

于 2012-12-04T19:33:50.467 回答