.net - Entity Framework 和多线程

标签 .net multithreading frameworks entity

我们在设计多线程 Entity Framework 驱动的应用程序时遇到一些问题,需要一些指导。我们在不同的线程上创建实体,将实体添加到集合中,然后将集合数据绑定(bind)到各种 WPF 控件。 ObjectContext 类不是线程安全的,因此对此进行管理我们基本上有 2 个解决方案:

解决方案 1 有一个上下文,并小心地使用锁定来确保没有 2 个线程同时访问它。这实现起来相对简单,但需要上下文在应用程序的持续时间内保持事件状态。像这样打开单个上下文实例是一个坏主意吗?

解决方案 2 是按需创建上下文对象,然后立即分离对象,然后将它们保存在我们自己的集合中,然后重新附加它们以进行任何更新。但这在使用中存在一些严重的问题,因为当对象分离时,它们会丢失对导航属性对象的引用。还有一个问题是,两个线程仍然可以尝试访问单个对象,并且都尝试将其 Attach() 到上下文。此外,每次我们想要访问实体的导航属性时,我们都需要提供一个新的上下文。

问:这两种解决方案是否有效?如果无效,您建议我们如何解决这个问题?

最佳答案

首先,我假设您已经阅读了这篇文章 "Multithreading and the Entity Framework"在 MSDN 上。

从线程角度来看,解决方案 #1 几乎肯定是最安全的,因为您可以保证在任何给定时间只有一个线程与上下文交互。保持上下文本身并没有什么问题——它不会在幕后保持数据库连接打开,所以这只是内存开销。当然,如果您最终在该线程上遇到瓶颈并且整个应用程序是使用单数据库线程假设编写的,那么这可能会带来性能问题。

解决方案 #2 对我来说似乎行不通 - 您最终会在整个应用程序中出现微妙的错误,人们会忘记重新附加(或分离)实体。

一种解决方案是不在应用程序的 UI 层中使用实体对象。无论如何,我建议这样做 - 很可能,实体对象的结构/布局对于您想要在用户界面上显示内容的方式来说并不是最佳的(这就是 MVC 模式系列的原因)。您的 DAL 应该具有特定于业务逻辑的方法(例如 UpdateCustomer),并且应该在内部决定是创建新的 Context 还是使用存储的上下文。您可以从单一存储上下文方法开始,然后如果遇到瓶颈问题,您需要进行更改的范围有限。

缺点是您需要编写更多代码 - 您将拥有 EF 实体,但您还会拥有具有重复属性的业务实体,并且许多 EF 实体的基数可能不同。为了缓解这种情况,您可以使用类似 AutoMapper 的框架简化将属性从 EF 实体复制到业务实体并再次复制回来的过程。

关于.net - Entity Framework 和多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9099359/

相关文章:

ios - 如何为iOS正确构建Swift框架

c# - 通过实现基础设施相关接口(interface)来污染域类型

c# - Thread.Join 与 Task.Wait

java - 重载 Thread.start()

java - 意外的线程唤醒

javascript - 在函数中将函数作为参数传递时调用私有(private)函数?

.net - 应用程序生命周期管理入门

c# - GetMethod 重载返回 null

.net - 使用 ILMerge 创建签名库抛出异常

php - 使用 Yii 模型创建或更新多个 mysql 行