我最近开始在我的。net 4.0应用程序中使用实体框架4.0,我对一些与池相关的事情很好奇。
Connection pooling as I know is managed by the ADO.NET data provider, in my case that of MS SQL server. Does this apply when you instantiate a new entities context (ObjectContext), i.e. the parameterless new MyDatabaseModelEntities()?
What are the advantages and disadvantages of a) creating a global entities context for the application (i.e. one static instance) or b) creating and exposing an entities context for each given operation/method, with a using block.
Any other recommendations, best practices, or common approaches for certain scenarios that I should know about?
根据EF6(4,5也)文件:
https://msdn.microsoft.com/en-us/data/hh949853#9
9.3每个请求的上下文
Entity Framework’s contexts are meant to be used as short-lived instances in order to provide the most optimal performance experience. Contexts are expected to be short lived and discarded, and as such have been implemented to be very lightweight and reutilize metadata whenever possible. In web scenarios it’s important to keep this in mind and not have a context for more than the duration of a single request. Similarly, in non-web scenarios, context should be discarded based on your understanding of the different levels of caching in the Entity Framework. Generally speaking, one should avoid having a context instance throughout the life of the application, as well as contexts per thread and static contexts.
Connection pooling is handled as in any other ADO.NET application. Entity connection still uses traditional database connection with traditional connection string. I believe you can turn off connnection pooling in connection string if you don't want to use it. (read more about SQL Server Connection Pooling (ADO.NET))
Never ever use global context. ObjectContext internally implements several patterns including Identity Map and Unit of Work. Impact of using global context is different per application type.
For web applications use single context per request. For web services use single context per call. In WinForms or WPF application use single context per form or per presenter. There can be some special requirements which will not allow to use this approach but in most situation this is enough.
如果你想知道单对象上下文对WPF / WinForm应用程序有什么影响,看看这篇文章。它是关于NHibernate会话,但思想是一样的。
编辑:
当您使用EF时,默认情况下每个上下文只加载一次每个实体。第一个查询创建实体实例并在内部存储它。任何需要具有相同键的实体的后续查询都会返回此存储实例。如果数据存储中的值发生了变化,您仍然会收到初始查询中值的实体。这称为标识映射模式。您可以强制对象上下文重新加载实体,但它将重新加载单个共享实例。
在调用上下文上的SaveChanges之前,对实体所做的任何更改都不会持久。您可以在多个实体中进行更改并一次性存储它们。这被称为工作单元模式。您不能有选择地说要保存哪个已修改的附加实体。
Combine these two patterns and you will see some interesting effects. You have only one instance of entity for the whole application. Any changes to the entity affect the whole application even if changes are not yet persisted (commited). In the most times this is not what you want. Suppose that you have an edit form in WPF application. You are working with the entity and you decice to cancel complex editation (changing values, adding related entities, removing other related entities, etc.). But the entity is already modified in shared context. What will you do? Hint: I don't know about any CancelChanges or UndoChanges on ObjectContext.
我认为我们不必讨论服务器场景。在多个HTTP请求或Web服务调用之间简单地共享单个实体会使应用程序毫无用处。任何请求都可以触发SaveChanges并保存来自另一个请求的部分数据,因为您正在所有请求之间共享单个工作单元。这还会有另一个问题——上下文和上下文中实体的任何操作或上下文使用的数据库连接都不是线程安全的。
即使对于只读应用程序,全局上下文也不是一个好选择,因为您可能希望每次查询应用程序时都有新的数据。
丹尼尔·西蒙斯表示:
Create a new ObjectContext instance in
a Using statement for each service
method so that it is disposed of
before the method returns.
This step is critical for scalability of your service. It makes sure that database connections are not kept open across service calls and that temporary state used by a particular operation is garbage collected when that operation is over. The Entity Framework automatically caches metadata and other information it needs in the app domain, and ADO.NET pools database connections, so re-creating the context each time is a quick operation.
这是他的一篇综合文章:
http://msdn.microsoft.com/en-us/magazine/ee335715.aspx
我相信这个建议可以扩展到HTTP请求,所以对ASP.NET也是有效的。有状态的胖客户端应用程序(例如WPF应用程序)可能是“共享”上下文的唯一情况。