实体框架最佳实践:哪一层应该调用SaveChanges()?

10

对于一个清洁的数据模型,我对此反复思考......

以批准工作流为例,假设在我的 Web 应用程序中有一个页面,允许用户标记一个需要批准的 MyEntityObjectMyEntityObject 有一些控制其批准工作流程的属性,因此我有一个通用的实用方法叫做 FlagForApproval(MyEntityObject eo)

应该让页面调用FlagForApproval()仅设置必要的属性,然后在准备好时调用SaveChanges(),还是FlagForApproval()保存更改?

让实用程序方法保存更改似乎比被要求做的多一点(如果它只是一系列操作中的一步呢?),但同时,让页面调用 SaveChanges() 并将数据提交到 DB 看起来可能被认为太接近数据层的职责。

你有什么想法吗?

(更新:值得一提的是,到目前为止,我一直让实用程序方法调用 SaveChanges(),这样页面只需要处理一个异常集,无论是验证还是数据。)

3个回答

2

我对这个问题的看法是,在验证数据后,始终让业务逻辑层调用保存更改。当用户点击保存按钮时,我将需要验证的实体传递给BLL,它决定是否SaveChanges()。

然而,我和你一样好奇,想知道其他人的看法,因为自从我开始使用EF以来,这个问题(以及许多其他问题)一直困扰着我。


我认为你是百分之百正确的-在 BLL 中保持 SaveChanges 很干净,让它决定是否执行保存非常干净。但是我可以看到至少有两种情况可以进行异常处理:1)项目需要对模型进行验证-它不是 BLL,但必须决定是否保存更改。2)SaveChanges 在非常简单的代码之后执行(添加实体,更新现有实体的单个属性)。在我的情况下,它将是 DAL。所以我想最好的解决方案是遵循你的直觉和/或经验。 - Piotr Justyna

1
关键是要将数据库和服务语言分开。如果实用程序方法需要保存更改,则执行保存,否则明确指出不保存并需要额外的步骤。实用程序不应该有一个名为SaveChanges的方法,而应该有与处理相关的方法,例如StartProcess或LoadToBatch。
将实用程序视为更多的服务,而不是数据库。 "FlagForApproval"听起来像是数据库操作,请尝试将该方法视为类似于“StartApprovalProcess”或其他与进程相关的内容。 StartApprovalProcess将执行所有工作并提交。
如果有多个步骤,请使每个步骤间接地指示可能还有更多步骤。只有最后一步才会提交。尽管最后一步可能只是保存更改,但让它读起来像移动或启动等过程。
例如:
  1. LoadToBatchApproval(MyEntityObject eo)

  2. ValidateApprovalBatch()...

  3. MoveBatchToProcessing()...


0

我不确定是否有正确或错误的答案,但是在我的看法中,让FlagForApproval处理启动工作流程的过程更加清晰。这包括告诉DataLayer持久化对象的状态(即SaveChanges)。然而,这假设您有业务要求,规定一旦启动工作流程,状态应该被持久化,以便在发生某些事情时(例如服务器崩溃),工作流程可以从上一个步骤继续进行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接