【问题标题】:Repository Pattern EF Core Update method存储库模式 EF Core 更新方法
【发布时间】:2019-12-03 09:10:13
【问题描述】:

我有一个关于在具有 Entity Framework Core 的 MVC Web 应用程序中使用存储库模式和工作单元模式的问题。

我目前正在控制器中实现更新功能。现在,在这一点上,我不确定更新实体的最佳方法是什么。我看过一些视频,他们说 Update 方法不应该出现在这样的存储库中:

public T Update(T entity)
{
  DbSet.Attach(entity);
  var entry = Context.Entry(entity);
  entry.State = System.Data.EntityState.Modified;
}

这意味着我必须在控制器中这样做:

public IActionResult Edit(int id, [Bind("NeighbourhoodGroup,Neighbourhood,NeighbourhoodId")] Neighbourhoods neighbourhoods)
{
  var neighbourhoodsFound = unitOfWork.Neighbourhoods.Get(id);
  neighbourhoodsFound.Neighbourhood = neighbourhoods.Neighbourhood;
  neighbourhoodsFound.NeighbourhoodGroup = neighbourhoods.NeighbourhoodGroup;
}

但是,这意味着我必须在所有控制器中执行此操作,即使对象有很多属性?

我希望有人能给我一些建议,告诉我最好的方法是什么。

【问题讨论】:

  • 您不需要更新方法。您也不需要存储库。您正在破坏 EF Core 并尝试重新实现已经实现的内容。顺便说一句,update 方法不会更新任何内容,它只会附加一个处于修改状态的分离实体。您确实需要附加一个新实体。
  • 检查No need for repositories and unit of work with Entity Framework CoreGunnar Peipman 在一篇文章中收集了这些通用存储库的所有问题

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


【解决方案1】:

在您的存储库中,您可以像这样简单地拥有更新功能:

public void Update(T entity)
    {
        DbSet.Attach(entity);
        ApplicationContext.Entry(entity).State = EntityState.Modified;
    }

在控制器中或从您喜欢进行更新的任何位置时,您可以最好通过 id 获取实体,修改您要在实体上修改的所有属性,从将要设置的存储库中调用 Update 方法它的状态被修改并最终在 EF 上下文中调用 Save 或 SaveAsync 方法。您的 EF 上下文应该在您的 UnitOfWork 中公开。

有关更详细的解释,您可以查看此帖子,这将非常有帮助。 EF Repository Pattern

【讨论】:

【解决方案2】:
  1. 我没有看到在存储库中有Update 方法的问题。没关系。根据标准从存储库中读取数据更为复杂。在这里您可以查看来自Microsoft 的示例。
  2. 控制器不是描述业务案例的好地方:执行一些业务逻辑,然后保存到存储库等。考虑将MediatR 作为描述特定业务案例的一种方式,而不是将其放入控制器中。

阅读clean architecture也很有用。

【讨论】:

  • 肯定不行。首先,拥有这样的 通用存储库 是一个非常糟糕的主意。您链接到的文章没有显示通用存储库,它显示了一个非常具体的存储库,它只添加了 EF 本身尚未提供的功能
  • 检查No need for repositories and unit of work with Entity Framework Core 以获得由通用存储库引起的问题列表。使用这些通用存储库,您将失去 UoW、无成本事务、批量更新并在更高级别的基础上强加低级别抽象
  • @PanagiotisKanavos 我相信通用存储库可以适用于某些类型的应用程序。是的,您应该在业务交易结束时提交更改。如果是 Web 应用程序,您可以在请求结束时执行此操作。但它没有直接连接到存储库。更多的是关于 dbcontext 的生命周期管理。
  • 通用存储库正试图成为灵丹妙药。您所指的是一个示例,说明了为什么您不需要需要一个通用存储库,以及如果您真的需要它们,使用事务是多么容易。你通常不会,因为SaveChanges 已经使用了事务。
  • 至于 repo 的生命周期,它是在 using 块中定义的。在 DI 场景中,当且仅当有适当的范围时,我们才能将生命周期管理留给其他人。例如,ASP.NET Core 处理所有作用域和瞬态服务(通过中间件)。尽管如此,没有调用SaveChanges,也没有更改回滚
猜你喜欢
  • 1970-01-01
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-15
相关资源
最近更新 更多