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

C# 实体框架最佳实践:哪个层应该调用SaveChanges()?,c#,database,entity-framework,C#,Database,Entity Framework,对于一个干净的数据模型,我将在这个问题上来回讨论 以审批工作流为例,假设在我的web应用程序中,有一个页面允许用户标记MyEntityObject进行审批MyEntityObject有几个属性控制其审批工作流,因此我有一个通用的实用方法,名为FlagForApproval(MyEntityObject eo) 页面是否应调用FlagForApproval()仅设置必要的属性,然后在准备就绪后调用SaveChanges(),还是应FlagForApproval()保存更改 让实用程序方法SaveC

对于一个干净的数据模型,我将在这个问题上来回讨论

以审批工作流为例,假设在我的web应用程序中,有一个页面允许用户标记
MyEntityObject
进行审批
MyEntityObject
有几个属性控制其审批工作流,因此我有一个通用的实用方法,名为
FlagForApproval(MyEntityObject eo)

页面是否应调用FlagForApproval()仅设置必要的属性,然后在准备就绪后调用SaveChanges(),还是应FlagForApproval()保存更改

让实用程序方法SaveChanges似乎比要求它做的要多一些(如果它只是一系列操作中的一个步骤呢?),但同时,让页面调用SaveChanges()并将数据提交给数据库似乎太接近数据层的职责

想法


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

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


我和你一样好奇,想看看别人怎么说,因为这个问题(以及许多其他问题)自从我开始使用EF以来一直困扰着我。

我不确定答案是否正确,但让FlagForApproval处理启动工作流的过程感觉更干净(imo)。这包括告诉数据层保持对象的状态(即SaveChanges)。但是,这假设您有业务需求,说明一旦启动工作流,状态应保持不变,因此,如果发生了什么事情(即服务器崩溃),工作流过程将从最后一步继续。

关键是分离数据库和服务语言。如果实用程序方法需要保存更改,那么它会保存更改,如果不保存,则说明它不保存更改,并且需要执行其他步骤。该实用工具不应具有名为SaveChanges的方法,而应具有与流程相关的方法,如StartProcess或LoadToBatch

将实用程序更多地视为一种服务,而不考虑数据库。“FlagForApproval”听起来像是一个数据库操作,试着将该方法想象成“StartApprovalProcess”或其他与流程相关的方法。StartApprovalProcess将完成所有工作并提交

如果有多个步骤,则使每个步骤间接指示可能有更多步骤。只有最后一步提交。尽管最后一步可能要做的只是保存更改,make的读取过程与move或start类似

例:

  • LoadToBatchApproval(MyEntityObject eo)

  • ValidateApprovalBatch()

  • MoveBatchToProcessing()


  • 我认为你是100%正确的-在BLL中保存更改并让它决定是否执行保存是非常干净的。但我可以看到至少有两种情况,其中一种例外情况是:1)项目需要在模型方面进行验证——它不是BLL,但它必须决定是否应该保存更改。2) SaveChanges在非常简单的代码(添加实体、更新现有实体的单个属性)之后执行。在我的情况下,这将是达尔。因此,我想最好的解决办法是跟随你的直觉和/或经验。