UnitOfWork 或 Repository 中的 DBContext SaveChanges 方法?哪个更好?
DBContext SaveChanges method in UnitOfWork or in Repository? Which is better?
我第一次尝试在已经遵循具有 Entity Framework DbContext 的存储库模式的 MVC 应用程序中使用工作单元模式。
我的问题是关于调用 Savechanges() 方法的最佳 place/practice。
我看到了 2 种可能的方法:
- 在工作单元中调用它class(Asp.Net site中提到的方法)
- 在存储库中调用 class
对于第一种方法,我们必须在控制器中注入的 UnitOfWork 实例上调用 SaveChanges()。
对于第二种方式,SaveChanges()会封装在Repository中,Controller只需要调用Repository中的方法(UnitOfWork提供),在Repository中调用SaveChanges()
方法一:
public class PostsController : Controller
{
private readonly IRepository<Post> _postRepository;
private readonly IRepository<Category> _categoryRepository;
private readonly IUnitOfWork _uow;
public PostsController(IUnitOfWork uow)
{
if (uow == null)
throw new ArgumentNullException(nameof(uow));
_uow = uow;
_postRepository = uow.Repository<Post>();
_categoryRepository = uow.Repository<Category>();
}
[HttpPost]
public ActionResult Create(Post post)
{
if (ModelState.IsValid)
{
_postRepository.Add(post);
_uow.SaveChanges();
}
return View(post);
}
}
public class UnitOfWork : IUnitOfWork
{
private CodingSoldierDbContext _dbContext;
private Dictionary<Type, object> _repositories = new Dictionary<Type, object>();
public UnitOfWork(DbContext dbContext)
{
if (dbContext == null)
throw new ArgumentNullException(nameof(dbContext));
_dbContext = dbContext as CodingSoldierDbContext;
}
public IRepository<T> Repository<T>() where T : class
{
if (_repositories.Keys.Contains(typeof(T)))
{
return _repositories[typeof(T)] as IRepository<T>;
}
IRepository<T> repository = new Repository<T>(_dbContext);
_repositories.Add(typeof(T), repository);
return repository;
}
public void SaveChanges()
{
_dbContext.SaveChanges();
}
}
public class Repository<T> : IRepository<T> where T : class
{
CodingSoldierDbContext _dbContext;
public Repository(DbContext dbContext)
{
if (dbContext == null)
throw new ArgumentNullException(nameof(dbContext));
_dbContext = dbContext as CodingSoldierDbContext;
}
public void Add(T item)
{
_dbContext.Set<T>().Add(item);
//_dbContext.SaveChanges();
}
}
方法二:
不添加代码,所以问题仍然很短。
在方法 1 中,在 Controller 中的 Create 方法中,删除行:
_uow.SaveChanges();
从 UnitOfWork 中删除 "SaveChanges" 方法定义。
取消注释存储库中的注释行 Class:
_dbContext.SaveChanges()
我觉得第二种方法比第一种方法更好,因为控制器中的代码更清晰,并且 SaveChanges 由直接与 DbContext 交互的 class(Repository) 负责。
任何人,如果您有任何理由我们应该遵循第一种方法,请告诉我?
两者都有。在 UOW 中,您需要将更改保存到复合存储库使用的上下文中。您还需要存储库中的 savechanges 方法,例如
public void SaveChanges()
{
context.SaveChanges();
}
对于独立使用的仓库
我更喜欢在 UnitOfWork 上下文中实现 SaveChanges,因为如果您编辑来自多个存储库的多个实体,您不想在每个存储库上执行保存更改。
示例:
var unitOfWork = UnitOfWorkFactory.Create();
var categoryRepo = unitOfWork.GetRepository<Category>();
var postRepo= unitOfWork.GetRepository<Post>();
var cat = new Category("name");
categoryRepo.Add(cat);
var post = new Post("Title", "Message");
post.Category = cat;
postRepo.Add(post );
unitOfWork.SaveChanges();
更容易保存完整的上下文(一次转换)。
我第一次尝试在已经遵循具有 Entity Framework DbContext 的存储库模式的 MVC 应用程序中使用工作单元模式。 我的问题是关于调用 Savechanges() 方法的最佳 place/practice。
我看到了 2 种可能的方法:
- 在工作单元中调用它class(Asp.Net site中提到的方法)
- 在存储库中调用 class
对于第一种方法,我们必须在控制器中注入的 UnitOfWork 实例上调用 SaveChanges()。 对于第二种方式,SaveChanges()会封装在Repository中,Controller只需要调用Repository中的方法(UnitOfWork提供),在Repository中调用SaveChanges()
方法一:
public class PostsController : Controller
{
private readonly IRepository<Post> _postRepository;
private readonly IRepository<Category> _categoryRepository;
private readonly IUnitOfWork _uow;
public PostsController(IUnitOfWork uow)
{
if (uow == null)
throw new ArgumentNullException(nameof(uow));
_uow = uow;
_postRepository = uow.Repository<Post>();
_categoryRepository = uow.Repository<Category>();
}
[HttpPost]
public ActionResult Create(Post post)
{
if (ModelState.IsValid)
{
_postRepository.Add(post);
_uow.SaveChanges();
}
return View(post);
}
}
public class UnitOfWork : IUnitOfWork
{
private CodingSoldierDbContext _dbContext;
private Dictionary<Type, object> _repositories = new Dictionary<Type, object>();
public UnitOfWork(DbContext dbContext)
{
if (dbContext == null)
throw new ArgumentNullException(nameof(dbContext));
_dbContext = dbContext as CodingSoldierDbContext;
}
public IRepository<T> Repository<T>() where T : class
{
if (_repositories.Keys.Contains(typeof(T)))
{
return _repositories[typeof(T)] as IRepository<T>;
}
IRepository<T> repository = new Repository<T>(_dbContext);
_repositories.Add(typeof(T), repository);
return repository;
}
public void SaveChanges()
{
_dbContext.SaveChanges();
}
}
public class Repository<T> : IRepository<T> where T : class
{
CodingSoldierDbContext _dbContext;
public Repository(DbContext dbContext)
{
if (dbContext == null)
throw new ArgumentNullException(nameof(dbContext));
_dbContext = dbContext as CodingSoldierDbContext;
}
public void Add(T item)
{
_dbContext.Set<T>().Add(item);
//_dbContext.SaveChanges();
}
}
方法二: 不添加代码,所以问题仍然很短。 在方法 1 中,在 Controller 中的 Create 方法中,删除行:
_uow.SaveChanges();
从 UnitOfWork 中删除 "SaveChanges" 方法定义。
取消注释存储库中的注释行 Class:
_dbContext.SaveChanges()
我觉得第二种方法比第一种方法更好,因为控制器中的代码更清晰,并且 SaveChanges 由直接与 DbContext 交互的 class(Repository) 负责。
任何人,如果您有任何理由我们应该遵循第一种方法,请告诉我?
两者都有。在 UOW 中,您需要将更改保存到复合存储库使用的上下文中。您还需要存储库中的 savechanges 方法,例如
public void SaveChanges()
{
context.SaveChanges();
}
对于独立使用的仓库
我更喜欢在 UnitOfWork 上下文中实现 SaveChanges,因为如果您编辑来自多个存储库的多个实体,您不想在每个存储库上执行保存更改。
示例:
var unitOfWork = UnitOfWorkFactory.Create();
var categoryRepo = unitOfWork.GetRepository<Category>();
var postRepo= unitOfWork.GetRepository<Post>();
var cat = new Category("name");
categoryRepo.Add(cat);
var post = new Post("Title", "Message");
post.Category = cat;
postRepo.Add(post );
unitOfWork.SaveChanges();
更容易保存完整的上下文(一次转换)。