如何在对数据库进行外部更改后更新/同步 DbContext

Posted

技术标签:

【中文标题】如何在对数据库进行外部更改后更新/同步 DbContext【英文标题】:How to update / synchronize DbContext after external changes to the database 【发布时间】:2019-04-19 19:24:10 【问题描述】:

我正在使用 Entity Framework 6,出于性能原因,我预先将我的实体加载到我的 DbContext 中,然后在本地使用它们。到目前为止,对数据库的所有更改都通过DbContext,因此我的本地实体和数据库已经同步。但是,我现在必须在数据库上调用存储过程,这具有对需要反映在我的实体中的表(在 DbContext 之外)进行更改的副作用。通过更改,我的意思是添加新记录和删除/更新现有记录。

我不想处理我的DbContext 并创建一个新的,因为一些实体实例包含在ViewModel 类中。因此,以这种方式删除DbContext 会导致UI 出现重大问题。

据我了解,只需在我的所有 DbSets 上调用 Load() 即可替换现有实例。因此,任何使用旧实体实例的对象都将不起作用。

所以,我想我可以使用Reload 方法,例如:

context.Entry(entity).Reload();

这将更新我的本地实体,但我只能对DbContext 已经知道的实体执行此操作。它不包括由于执行存储过程而创建/删除的任何 NEW 实体或 DELETED 实体。

所以,我正在寻找一种方法:

    从数据库中加载对我的DbContext 新的实体 在我的DbContext 中重新加载现有实体 从我的DbContext 中删除所有已删除的实体

【问题讨论】:

你不能在实体框架中映射你的存储过程吗?它们是 db 对象,可以像对表一样进行映射。我认为,如果您将它们映射到模型中,您的上下文将反映由它们引起的变化。您是否已经尝试过这种方法? @moro91 首先,我不知道你能做到这一点,即让 DbContext 对存储过程做出反应。但无论如何,我没有“模型”。 所以您使用的是代码优先方法,您不需要从现有数据库中请求自动映射?在这里你可以找到关于这个话题的简单解释:entityframeworktutorial.net/entityframework6/… @moro91 ,感谢您的回复,但我不明白链接中的信息。似乎表明存储过程将在 DbContext.SaveChanges() 上执行,但这不是我想要发生的。 SP 在不同的时间执行。无论如何,我不确定我是否理解链接中的示例以及它在我的场景中的工作方式,因为不止一个表会受到其操作的影响。 如果存储过程被某些不属于您通常的应用程序数据访问的东西触发,那么您将无法在 dbcontext 中自动更新数据,因为您正在使用预加载。您的 dbcontext 很重且不太一致。您必须获取更新数据的唯一方法是每次都完全重新加载上下文。我想我错过了一些信息:它是 Web 应用程序还是桌面应用程序?是单用户还是多用户?你如何处理数据的并发性?我认为这些先决条件对于评估解决问题的最佳方法非常重要。 【参考方案1】:

这里是实体框架的官方文档。 从分析您的数据库情况开始,它建议智能和快速的方法来获取您想要的内容,详细说明必要时的数据读取策略(如急切或延迟加载)或提供正确使用代码生成和向导 GUI 的教程。

http://www.entityframeworktutorial.net/choosing-development-approach-with-entity-framework.aspx

这里有一些关于数据读取策略的更详细信息和教程:https://www.c-sharpcorner.com/article/eager-loading-lazy-loading-and-explicit-loading-in-entity-framework/

正如我在 cmets 中已经告诉你的,我建议采用数据库优先的方法并使用延迟加载来避免不受控制的数据行为(或在运行存储过程时重新加载整个数据库)。

说到SP,可以简单的通过Entity Framework自带的Wizard进行映射,用方法封装。

希望这些资源对您有所帮助!

【讨论】:

感谢您提供此信息。你能扩展我在哪里可以找到映射 SP 的向导吗?即使我坚持当前的“代码优先”策略而不是采用数据库优先方法,我也可以这样做吗? 这是您开始时需要知道的一切:docs.microsoft.com/en-us/ef/ef6/modeling/designer/workflows/… 再次感谢您的帮助。非常感谢。【参考方案2】:

一般而言,EntityFramework 无法感知数据库的变化并更新dbcontext。没有针对它的优化或 EntityFramework 内置解决方案。

我认为您可以在 SqlServer 中使用 CDC,将更改推送到您的应用程序并更新您的 dbcontext。但它不是所有业务和场景都可接受的解决方案

【讨论】:

以上是关于如何在对数据库进行外部更改后更新/同步 DbContext的主要内容,如果未能解决你的问题,请参考以下文章

更改更新核心数据属性的删除方法

如何告诉 ExtJS Grid 编辑过的数据已经同步?

在对 Apache2 进行安全更新后,我的 CORS 请求开始失败。我不知道为啥。

如何一次性同步内存中的集合与其后备数据库表

第六周总结

AD更改登陆账户名后,后XenDesktop DDC无法同步用户信息