关于.net:实体框架和连接池

Entity Framework and Connection Pooling

我最近开始在我的.NET 4.0应用程序中使用EntityFramework4.0,并且对一些与池相关的事情感到好奇。

  • 据我所知,连接池是由ADO.NET数据提供程序管理的,在我的情况下是由MS SQL Server管理的。当您实例化一个新的实体上下文(ObjectContext时,即无参数的new MyDatabaseModelEntities()时,这是否适用?

  • a)为应用程序创建全局实体上下文(即一个静态实例)或b)为每个给定的操作/方法创建和公开实体上下文(使用using块),其优点和缺点是什么?

  • 对于我应该了解的某些场景,还有其他建议、最佳实践或常见方法吗?


  • 连接池的处理方式与任何其他ADO.NET应用程序相同。实体连接仍然使用传统的数据库连接和传统的连接字符串。我相信如果不想使用连接字符串中的连接池,您可以关闭它。(阅读有关SQL Server连接池(ADO.NET)的详细信息)
  • 永远不要使用全局上下文。ObjectContext在内部实现了几个模式,包括标识映射和工作单元。使用全局上下文对每个应用程序类型的影响是不同的。
  • 对于Web应用程序,每个请求使用单个上下文。对于Web服务,每次调用使用单个上下文。在WinForms或WPF应用程序中,每个窗体或每个演示者使用单个上下文。可能有一些特殊的要求不允许使用这种方法,但在大多数情况下,这已经足够了。
  • 如果您想知道对WPF/WinForm应用程序的单个对象上下文有什么影响,请检查本文。这是关于NHibernate会议,但想法是一样的。

    编辑:

    使用ef时,默认情况下,每个上下文只加载一次每个实体。第一个查询创建实体实例并将其存储在内部。任何需要具有相同键的实体的后续查询都会返回此存储实例。如果数据存储区中的值发生更改,您仍然可以从初始查询接收包含值的实体。这被称为身份映射模式。可以强制对象上下文重新加载实体,但它将重新加载单个共享实例。

    在上下文中调用SaveChanges之前,对实体所做的任何更改都不会持久。您可以在多个实体中进行更改并同时存储它们。这被称为工作单元模式。不能有选择地说出要保存的修改后的附加实体。

    结合这两种模式,您将看到一些有趣的效果。整个应用程序只有一个实体实例。对实体的任何更改都会影响整个应用程序,即使更改尚未持久化(提交)。在大多数情况下,这不是你想要的。假设您在WPF应用程序中有一个编辑表单。您正在处理该实体,并决定取消复杂的编辑(更改值、添加相关实体、删除其他相关实体等)。但是该实体已经在共享上下文中进行了修改。你会怎么做?提示:我不知道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应用程序)可能是"共享"上下文的唯一情况。


    根据该文件ef6(4.5 also to):msdn.microsoft.com HTTPS:/ / / / / hh949853销售额# 9日P></

    9.3 context为requestP></

    S是framework' entity to be used as的意思是语境中的短lived阶情况下提供最最优性能的经验。语境are expected to be short lived和have been discarded without这样,当要实现再利用元数据和lightweight to be possible甚当。在Web是important to keep this场景在心灵和not have a context for the duration of a超过单个请求。similarly,非Web context should be discarded without场景,基于不同层次的理解of the of the entity的缓存框架。generally说,在一审有avoid should the context of the application的整个生命,对As和As线程静态语境是语境。P></


    下面的代码帮助我的对象使用新的数据库值进行刷新。entry(object).reload()命令强制对象调用数据库值

    1
    2
    GM_MEMBERS member = DatabaseObjectContext.GM_MEMBERS.FirstOrDefault(p => p.Username == username && p.ApplicationName == this.ApplicationName);
    DatabaseObjectContext.Entry(member).Reload();