实体框架 + SQL Server Compact + WPF/WinForms = 缓慢的 UI?

Posted

技术标签:

【中文标题】实体框架 + SQL Server Compact + WPF/WinForms = 缓慢的 UI?【英文标题】:Entity Framework + SQL Server Compact + WPF/WinForms = Sluggish UI? 【发布时间】:2014-03-26 15:54:56 【问题描述】:

实体框架不允许在多个数据库上下文之间共享同一个实体。因此,我必须在 GUI 应用程序中仅使用一个数据库上下文(无论是 WPF或 WinForms),因为实体需要相互交互。

SQL Server Compact 不允许在多个线程之间共享同一个数据库连接。如果我尝试在一个线程上创建连接并在另一个线程上运行 SQL 查询,我的应用程序可能会崩溃。

因此,我必须在一个线程上创建 EF 数据库上下文并在该线程上运行所有查询。我为此使用了 GUI 线程,因为几乎所有查询都非常快。但是,现在我的查询速度很慢,想在执行时显示一个动画进度条。

但我不能这样做,因为如果我在不同的线程上运行查询,我的应用程序会因 AV 崩溃。此外,如果我同时运行多个查询,EF 似乎会抱怨,即使没有涉及 SQL CE。将所有查询移动到不同的线程,用大量的异步/等待、回调、锁和其他线程处理覆盖所有代码,这听起来也很可怕,因为我希望尽可能保持代码简单。

问题:在多线程 GUI 应用程序中使用 EF 数据库上下文和 SQL Server Compact 的正确方法是什么?有什么方法可以在不使整个应用程序异步的情况下将单个查询卸载到不同的线程,即是否有一种简单的方法可以做到这一点?

【问题讨论】:

但是你可以有一个调用来创建一个 dbcontext、打开一个连接、执行一个查询、处理结果并返回一个列表/数据集,不是吗? @rene 这是 GUI 应用程序。请求的实体被编辑,连接的实体被创建/编辑,有自动完成和其他对实体进行操作的功能。如果我从一个 dbcontext 中获取一个实体,然后将另一个 dbcontext 中的另一个实体放入其导航属性中,EF 会抱怨。这些操作在时间上是分开的,我事先不知道用户需要什么实体。 根据我使用 EF 作为自上而下的 ORM 的经验,除了最简单的 GUI 之外,这是一条疯狂之路。需要在内存中拥有多个实体并连接到上下文表明您正在使用 EF 进行业务逻辑,这正是引发此类问题的原因。相反,请考虑将其严格用作 DAL 来处理单独对象模型的 CRUD 函数。 【参考方案1】:

SQL Server CE 支持多线程。但它的对象,如 SqlCeConnection 或 SqlCeTransaction 不是线程安全的。每个线程都应使用单独的连接。 实体框架 DataContext 实例旨在持续一个工作单元(业务事务)。 The recommendation 是每个表单的上下文。

您可以使用DTOs 重新设计您的应用程序并存储/传输数据。或者您可以使用实体框架的附加/分离功能(here 或here)。或者将两者结合起来。

【讨论】:

每个表单的一个上下文只有在表单很简单时才能正常工作。假设我在表单中具有需要慢查询的搜索功能。如果我将查询移动到另一个线程,我将无法使用收到的实体。如果我分离并重新连接它们,我会丢失连接的实体、延迟加载、更改跟踪;当已经附加了具有相同 ID 的实体时,我也可能会遇到这种情况。如果我使用 DTO 并且不存储上下文,则结果相似,但代码更多且没有 id 冲突。我没有看到任何不牺牲 EF 主要功能的解决方案。

以上是关于实体框架 + SQL Server Compact + WPF/WinForms = 缓慢的 UI?的主要内容,如果未能解决你的问题,请参考以下文章

实体框架和SQL Server Compact Edition DDEX提供程序

使用 SQL Server Compact 4.0 在实体框架中进行 LIKE 查询

在 SQL Server Compact Edition 中将实体框架代码中的主键首先播种为 0

如果我们使用实体框架和代码优先方法,是不是可以在给定路径上创建数据库(Sql Server compact)?

使用 SQL Server Compact Edition 的 Linq-to-SQL

实体数据模型向导在 vs 2012 中未显示 Microsoft SQL Server Compact 3.5