我最近开始在我的 .NET 4.0 应用程序中使用 Entity Framework 4.0,并对与池相关的一些事情感到好奇。
据我所知,连接池由 ADO.NET 数据提供程序管理,在我的例子中是 MS SQL 服务器。当您实例化一个新的实体上下文 ( ObjectContext) 时,这是否适用,即无参数new MyDatabaseModelEntities()?
ObjectContext
new MyDatabaseModelEntities()
a)为应用程序创建一个全局实体上下文(即一个静态实例)或b)为每个给定的操作/方法创建和公开一个实体上下文的优点和缺点是什么,使用一个using块。
using
对于某些场景,我应该了解的任何其他建议、最佳实践或常用方法?
如果您想了解 WPF/WinForm 应用程序的单个对象上下文有什么影响,请查看这篇文章。这是关于 NHibernate Session 但想法是一样的。
编辑:
当您使用 EF 时,默认情况下每个上下文仅加载每个实体一次。第一个查询创建实体实例并将其存储在内部。任何需要具有相同键的实体的后续查询都会返回此存储的实例。如果数据存储中的值发生更改,您仍会收到带有初始查询值的实体。这称为 身份映射模式 。您可以强制对象上下文重新加载实体,但它会重新加载单个共享实例。
SaveChanges在调用上下文之前,对实体所做的任何更改都不会保留。您可以对多个实体进行更改并一次存储它们。这称为 工作单元模式 。您不能有选择地说出要保存哪个修改后的附加实体。
SaveChanges
结合这两种模式,你会看到一些有趣的效果。整个应用程序只有一个实体实例。即使更改尚未持久化(提交),对实体的任何更改也会影响整个应用程序。在大多数情况下,这不是您想要的。假设您在 WPF 应用程序中有一个编辑表单。您正在使用实体并决定取消复杂的编辑(更改值、添加相关实体、删除其他相关实体等)。但是实体已经在共享上下文中进行了修改。你会怎么做?提示:我不知道任何 CancelChanges 或 UndoChanges on ObjectContext.
我认为我们不必讨论服务器场景。简单地在多个 HTTP 请求或 Web 服务调用之间共享单个实体会使您的应用程序毫无用处。任何请求都可以触发SaveChanges并保存来自另一个请求的部分数据,因为您在所有请求之间共享单个工作单元。这也会有另一个问题——上下文和对上下文中实体的任何操作或上下文使用的数据库连接都不是线程安全的。
即使对于只读应用程序,全局上下文也不是一个好的选择,因为您可能每次查询应用程序时都需要新数据。