Entity Framework 6和Unit Of Work... 在哪里,什么时候? 它是否类似于ado.net中的事务?

24 浏览
0 Comments

Entity Framework 6和Unit Of Work... 在哪里,什么时候? 它是否类似于ado.net中的事务?

创建一个新的MVC项目,喜欢在数据层中使用仓库的想法,所以我已经实现了它们。我还创建了一个服务层来处理所有的业务逻辑和验证,该层使用相应的仓库。类似这样(我使用Simple Injector来注入):

数据访问层

public class MyRepository {
    private DbContext _context;
    public MyRepository(DbContext context) {
        _context = context;
    }    
    public MyEntity Get(int id)
    {
        return _context.Set().Find(id);
    }
    public TEntity Add(MyEntity t)
    {
        _context.Set().Add(t);
        _context.SaveChanges();
        return t;
    }
    public TEntity Update(MyEntity updated, int key)
    {
        if (updated == null)
            return null;
        MyEntity existing = _context.Set().Find(key);
        if (existing != null)
        {
            _context.Entry(existing).CurrentValues.SetValues(updated);
            _context.SaveChanges();
        }
        return existing;
    }
    public void Delete(MyEntity t)
    {
        _context.Set().Remove(t);
        _context.SaveChanges();
    }
}

服务层

public class MyService {
    private MyRepository _repository;
    public MyService(MyRepository repository) {
        _repository = repository;    
    }
    public MyEntity Get(int id)
    {
        return _repository.Get(id);
    }
    public MyEntity Add(MyEntity t)
    {
        _repository.Add(t);
        return t;
    }
    public MyEntity Update(MyEntity updated)
    {
        return _repository.Update(updated, updated.Id);
    }
    public void Delete(MyEntity t)
    {
        _repository.Delete(t);
    }
}

现在这很简单,所以我可以使用以下代码来更新对象。

MyEntity entity = MyService.Get(123);
MyEntity.Name = "HELLO WORLD";
entity = MyService.Update(entity);

或者使用以下代码创建一个对象

MyEntity entity = new MyEntity();
MyEntity.Name = "HELLO WORLD";
entity = MyService.Add(entity);
// entity.Id现在已经填充

现在假设我需要根据另一个对象的创建ID来更新一个项目,我可以使用上面的代码没有问题,但是如果发生错误怎么办?我需要某种形式的事务/回滚。这就是UnitOfWork模式所解决的问题吗?

所以我猜我需要在我的UnitOfWork对象中有DbContext,所以我像这样创建一个对象?

public class UnitOfWork : IDisposable {
    private DbContext _context;
    public UnitOfWork(DbContext context) {
        _context = context;
    }
    public Commit() {
        _context.SaveChanges();
    }
    public Dispose() {
        _context.Dispose();
    }
}

好的,这又很简单。UnitOfWork也持有上下文(我在所有仓库上都使用相同的上下文),并调用SaveChanges()方法。然后我会从我的仓库中删除SaveChanges()方法调用。所以要添加,我会这样做:

UnitOfWork uow = new UnitOfWork(new DbContext()); // 我会以某种方式注入这个
MyEntity entity = new MyEntity();
MyEntity.Name = "HELLO WORLD";
entity = MyService.Add(entity);
uow.Commit();

但是如果我需要创建一个对象,然后根据该ID更新其他对象,那么现在将无法工作,因为在调用uow的Commit之前,ID将不会被创建。例如:

UnitOfWork uow = new UnitOfWork(new DbContext()); // 我会以某种方式注入这个
MyEntity entity = new MyEntity();
MyEntity.Name = "HELLO WORLD";
entity = MyService.Add(entity);
// entity.Id没有被填充
MyEntity otherEntity = MyService.Get(123);
otherEntity.OtherProperty = entity.Id;
MyService.Update(otherEntity);
uow.Commit();  // otherEntity.OtherProperty没有连接......?

所以我觉得这个UnitOfWork类不对...可能我误解了什么。我需要能够添加一个实体并获取该ID,并在另一个实体上使用它,但是如果发生错误,我希望能够"回滚",就像ado.net事务一样。

使用Entity Framework和Repositories是否可以实现这种功能?

0