【问题标题】:DBContext SaveChanges method in UnitOfWork or in Repository? Which is better?UnitOfWork 或存储库中的 DBContext SaveChanges 方法?哪个更好?
【发布时间】:2023-03-25 12:23:02
【问题描述】:

我第一次尝试在 MVC 应用程序中使用工作单元模式,该应用程序已经遵循带有实体框架 DbContext 的存储库模式。 我的问题是关于调用 Savechanges() 方法的最佳位置/实践。

我看到两种可能的方法:

  1. 在工作单元类中调用它(Asp.Net site 中提到的方法)
  2. 在存储库类中调用

对于第一种方法,我们必须在 Controller 中注入的 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”方法定义。

在 Repository Class 中取消注释注释行:

_dbContext.SaveChanges()

我觉得在控制器中的感觉代码中,第二种方法比第一种方法更干净,并且 SaveChanges 是直接与 DbContext 交互的同一个类(存储库)的责任。

任何人,如果您有任何理由我们应该遵循第一种方法,请告诉我?

【问题讨论】:

  • tion 评估需要所有线程运行 c# wpf

标签: c# asp.net-mvc entity-framework repository-pattern


【解决方案1】:

我更喜欢在 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();

保存完整的上下文更容易(在一个转换中)。

【讨论】:

    【解决方案2】:

    两者兼而有之。在 UOW 中,您需要保存对复合存储库使用的上下文的更改。您还需要存储库中的 savechanges 方法,例如

    public void SaveChanges() 
    {
        context.SaveChanges(); 
    }
    

    对于独立使用的仓库

    【讨论】:

      猜你喜欢
      • 2013-08-08
      • 1970-01-01
      • 1970-01-01
      • 2019-03-29
      • 1970-01-01
      • 1970-01-01
      • 2022-11-04
      • 2013-11-12
      • 1970-01-01
      相关资源
      最近更新 更多