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

时间:2021-04-01 20:04:40

For a clean data model, I'm going back and forth on this...

对于一个干净的数据模型,我会来回这个......

Using an approval workflow as an example, let's say in my web application I have a page that lets a user flag a MyEntityObject for approval. MyEntityObject has a few properties that control its approval workflow, so I have a common utility method out there called FlagForApproval(MyEntityObject eo).

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

Should the page call FlagForApproval() to set necessary properties only and then call SaveChanges() when it's ready, or should FlagForApproval() save the changes?

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

Having the utility method save changes seems like it's doing a little more than it's asked to do (what if it was just one step in a series of operations?), but at the same time, making the page call SaveChanges() and commit the data to the DB seems like it could be considered too close to data layer responsibilities.

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

Thoughts?

思考?

(Update: FWIW, so far I have been having utility methods call SaveChanges(), that way the page only has one set of exceptions to handle, whether validation or data.)

(更新:FWIW,到目前为止我一直在使用实用方法调用SaveChanges(),这样页面只有一组异常要处理,无论是验证还是数据。)

3 个解决方案

#1


2  

My current opinion on this issue is to always have the business logic layer call save changes after validating data. When the user clicks Save button, i pass whatever entities need to be validated down to the BLL, and it decides whether to SaveChanges().

我目前对此问题的看法是在验证数据后始终让业务逻辑层调用保存更改。当用户单击“保存”按钮时,我将需要验证的任何实体传递给BLL,并决定是否使用SaveChanges()。

I'm as curious as you though, to see what others say because this issue (and many other) has been plaguing me since i started with EF.

我和你一样好奇,看看别人怎么说,因为这个问题(还有很多其他的)一直困扰着我,因为我从EF开始。

#2


1  

The key is to separate Database and Service language. If the utility method needs to save changes then it does, if not make it clear that it does not and additional steps are needed. The utility should not have a method called SaveChanges, it should have process related methods, like StartProcess or LoadToBatch.

关键是分离数据库和服务语言。如果实用程序方法需要保存更改,那么如果没有明确表示它没有,则需要执行其他步骤。该实用程序不应该有一个名为SaveChanges的方法,它应该有与进程相关的方法,如StartProcess或LoadToBatch。

View the utility as more of a service and do not think database. The "FlagForApproval" sounds like a database operation, try thinking of the method as something like "StartApprovalProcess" or something else process related. StartApprovalProcess would do all work and commits.

将该实用程序视为更多服务而不考虑数据库。 “FlagForApproval”听起来像一个数据库操作,尝试将该方法视为“StartApprovalProcess”或其他与进程相关的东西。 StartApprovalProcess将完成所有工作和提交。

If there are multiple steps, make each step indicate indirectly that there may be more steps. Only the last step commits. Allthough all the last step may do is save changes, make is read like a process such as move or start.

如果有多个步骤,请使每个步骤间接指示可能有更多步骤。只有最后一步提交。尽管所有最后一步可能都是保存更改,但是读取就像移动或启动等过程一样。

Ex:

例如:

  1. LoadToBatchApproval(MyEntityObject eo)

    LoadToBatchApproval(MyEntityObject eo)

  2. ValidateApprovalBatch()...

    ValidateApprovalBatch()...

  3. MoveBatchToProcessing()...

    MoveBatchToProcessing()...

#3


0  

I'm not sure there is a right or wrong answer, but it feels cleaner (imo) to have FlagForApproval handle the process for starting the workflow. That includes telling the DataLayer to persist the state of the object (i.e. SaveChanges). However this assumes that you have business requirements stating that once a workflow is started the state should be persisted so if something happens (i.e. server crashes) the workflow process continues from last step.

我不确定是否有正确或错误的答案,但让FlagForApproval处理启动工作流程的过程感觉更清晰(imo)。这包括告诉DataLayer持久化对象的状态(即SaveChanges)。但是,这假设您有业务要求,声明一旦工作流启动,状态应该保持不变,因此如果发生某些事情(即服务器崩溃),工作流程将从上一步继续。

#1


2  

My current opinion on this issue is to always have the business logic layer call save changes after validating data. When the user clicks Save button, i pass whatever entities need to be validated down to the BLL, and it decides whether to SaveChanges().

我目前对此问题的看法是在验证数据后始终让业务逻辑层调用保存更改。当用户单击“保存”按钮时,我将需要验证的任何实体传递给BLL,并决定是否使用SaveChanges()。

I'm as curious as you though, to see what others say because this issue (and many other) has been plaguing me since i started with EF.

我和你一样好奇,看看别人怎么说,因为这个问题(还有很多其他的)一直困扰着我,因为我从EF开始。

#2


1  

The key is to separate Database and Service language. If the utility method needs to save changes then it does, if not make it clear that it does not and additional steps are needed. The utility should not have a method called SaveChanges, it should have process related methods, like StartProcess or LoadToBatch.

关键是分离数据库和服务语言。如果实用程序方法需要保存更改,那么如果没有明确表示它没有,则需要执行其他步骤。该实用程序不应该有一个名为SaveChanges的方法,它应该有与进程相关的方法,如StartProcess或LoadToBatch。

View the utility as more of a service and do not think database. The "FlagForApproval" sounds like a database operation, try thinking of the method as something like "StartApprovalProcess" or something else process related. StartApprovalProcess would do all work and commits.

将该实用程序视为更多服务而不考虑数据库。 “FlagForApproval”听起来像一个数据库操作,尝试将该方法视为“StartApprovalProcess”或其他与进程相关的东西。 StartApprovalProcess将完成所有工作和提交。

If there are multiple steps, make each step indicate indirectly that there may be more steps. Only the last step commits. Allthough all the last step may do is save changes, make is read like a process such as move or start.

如果有多个步骤,请使每个步骤间接指示可能有更多步骤。只有最后一步提交。尽管所有最后一步可能都是保存更改,但是读取就像移动或启动等过程一样。

Ex:

例如:

  1. LoadToBatchApproval(MyEntityObject eo)

    LoadToBatchApproval(MyEntityObject eo)

  2. ValidateApprovalBatch()...

    ValidateApprovalBatch()...

  3. MoveBatchToProcessing()...

    MoveBatchToProcessing()...

#3


0  

I'm not sure there is a right or wrong answer, but it feels cleaner (imo) to have FlagForApproval handle the process for starting the workflow. That includes telling the DataLayer to persist the state of the object (i.e. SaveChanges). However this assumes that you have business requirements stating that once a workflow is started the state should be persisted so if something happens (i.e. server crashes) the workflow process continues from last step.

我不确定是否有正确或错误的答案,但让FlagForApproval处理启动工作流程的过程感觉更清晰(imo)。这包括告诉DataLayer持久化对象的状态(即SaveChanges)。但是,这假设您有业务要求,声明一旦工作流启动,状态应该保持不变,因此如果发生某些事情(即服务器崩溃),工作流程将从上一步继续。