C# DbContext的自定义连接打开/关闭
默认情况下,EF Core为每个查询打开和关闭一个C# DbContext的自定义连接打开/关闭,c#,entity-framework-core,database-connection,ef-core-3.1,C#,Entity Framework Core,Database Connection,Ef Core 3.1,默认情况下,EF Core为每个查询打开和关闭一个DbConnection,除非您传入一个已经打开的连接 我有,所以我不希望每次都打开和关闭连接,而是希望每次保持连接打开五秒钟,同时为每个查询/命令重用该连接。(上面链接的问题的解决方案使连接在DBContext的整个生命周期中保持打开状态。) 抛开锁定/并发问题不谈,我在哪里可以在DbContext中注入自定义连接解析/打开逻辑?差不多 before executing query: if connection is not open
DbConnection
,除非您传入一个已经打开的连接
我有,所以我不希望每次都打开和关闭连接,而是希望每次保持连接打开五秒钟,同时为每个查询/命令重用该连接。(上面链接的问题的解决方案使连接在DBContext的整个生命周期中保持打开状态。)
抛开锁定/并发问题不谈,我在哪里可以在DbContext
中注入自定义连接解析/打开逻辑?差不多
before executing query:
if connection is not open
open
set timer to fire close request in five seconds
take lock on connection (to prevent closing)
execute query
release lock
这是做交易的标准方式。 您可以组合多个查询
using (var context = new SchoolContext())
{
var std = new Student()
{
FirstName = "Bill",
LastName = "Gates"
};
context.Students.Add(std);
// or
// context.Add<Student>(std);
context.SaveChanges();
std = context.Students.First<Student>();
std.FirstName = "Steve";
context.SaveChanges();
}
EF6和未来版本中的行为
对于EF6和未来的版本,我们采取的方法是,如果调用代码选择通过调用context.Database.connection.open()打开连接,那么这样做是有充分理由的,框架将假定它想要控制连接的打开和关闭,并且不再自动关闭连接
注
这可能会导致连接长时间打开,因此请小心使用
我们还更新了代码,以便ObjectContext.Connection.State现在可以正确跟踪底层连接的状态
using System;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Core.EntityClient;
using System.Data.Entity.Infrastructure;
namespace ConnectionManagementExamples
{
internal class DatabaseOpenConnectionBehaviorEF6
{
public static void DatabaseOpenConnectionBehavior()
{
using (var context = new BloggingContext())
{
// At this point the underlying store connection is closed
context.Database.Connection.Open();
// Now the underlying store connection is open and the
// ObjectContext.Connection.State correctly reports open too
var blog = new Blog { /* Blog’s properties */ };
context.Blogs.Add(blog);
context.SaveChanges();
// The underlying store connection remains open for the next operation
blog = new Blog { /* Blog’s properties */ };
context.Blogs.Add(blog);
context.SaveChanges();
// The underlying store connection is still open
} // The context is disposed – so now the underlying store connection is closed
}
}
}
在ADO.NET中,您可以配置连接池以满足您的需求 将为每个唯一的连接字符串创建一个连接池。创建池时,将创建多个连接对象并将其添加到池中,以满足最小池大小要求。根据需要将连接添加到池中,最多可达到指定的最大池大小(默认值为100)。连接在关闭或释放时释放回池中 连接池器通过在连接释放回池中时重新分配连接来满足连接请求。如果已达到最大池大小且没有可用连接,则请求将排队。池程序然后尝试回收所有连接,直到达到超时(默认值为15秒)。如果池程序在连接超时之前无法满足请求,则会引发异常 在连接池空闲约4-8分钟后,或者如果连接池检测到与服务器的连接已断开,则连接池将从连接池中删除连接。请注意,只有在尝试与服务器通信后才能检测到断开的连接。如果发现不再连接到服务器的连接,则会将其标记为无效。无效连接只有在关闭或回收时才会从连接池中删除 如果
SqlConnection
超出范围,它将不会被关闭。
因此,您必须通过调用close
或处置
<代码>关闭和处置
在功能上是等效的。如果
连接池值pooling
设置为true
或是,则
基础连接返回到连接池。上
另一方面,如果池设置为false或no,则底层
与服务器的连接实际上已关闭
你们可以在文章中阅读更多细节。
核心和连接池
相关问题 我认为底层db驱动程序通常提供连接池,这应该能够重用连接。还可以查看EF core中的上下文池:使用EF core控制连接池肯定有一种简单的方法——假设这就是您想要的。(或者每个查询需要不同的连接吗?)对不起,原来的问题描述错误。我想问的是让连接保持打开状态,以便根据计时器进行多个查询,但不是在上下文的整个生命周期内。我想知道我是否可以使用…检查编辑,在我看来,使用内部计时器可以从中受益。仔细想想,它与连接池非常相似。你考虑过连接池吗?我相信OP是在寻找
EF Core
解决方案吗?@timur我相信我在start中写道,他可以组合方法。我对其进行了编辑以使其更有意义。这可能导致连接长时间打开,因此请小心使用。
。这就是我试图通过定时器打开和关闭它来实现的。对不起,我原来的帖子措词不好。这不是我需要的解决方案;请看我对这个问题的更正。但我认为itDBContextPooling是在不同的DbContexts请求之间重用DbContexts;我想在单个DbContextA DbContext中重用连接。DbContext如何仅在打开的连接上进行,进行自己的连接池可能会导致性能问题,例如SqlServer上的连接耗尽
public DbContext(DbConnection existingConnection, bool contextOwnsConnection)
public DbContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection)
using System;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Core.EntityClient;
using System.Data.Entity.Infrastructure;
namespace ConnectionManagementExamples
{
internal class DatabaseOpenConnectionBehaviorEF6
{
public static void DatabaseOpenConnectionBehavior()
{
using (var context = new BloggingContext())
{
// At this point the underlying store connection is closed
context.Database.Connection.Open();
// Now the underlying store connection is open and the
// ObjectContext.Connection.State correctly reports open too
var blog = new Blog { /* Blog’s properties */ };
context.Blogs.Add(blog);
context.SaveChanges();
// The underlying store connection remains open for the next operation
blog = new Blog { /* Blog’s properties */ };
context.Blogs.Add(blog);
context.SaveChanges();
// The underlying store connection is still open
} // The context is disposed – so now the underlying store connection is closed
}
}
}
using (SqlConnection connection = new SqlConnection("Integrated Security=SSPI;Initial Catalog=Northwind"))
{
connection.Open();
// Pool A is created.
}
using (SqlConnection connection = new SqlConnection("Integrated Security=SSPI;Initial Catalog=pubs"))
{
connection.Open();
// Pool B is created because the connection strings differ.
}
using (SqlConnection connection = new SqlConnection("Integrated Security=SSPI;Initial Catalog=Northwind"))
{
connection.Open();
// The connection string matches pool A.
}