EF Core默认情况下会为每个查询打开和关闭DbConnection
,除非您传入已经打开的连接。
我有lots of small queries,所以我不想每次都打开和关闭一个连接,而是一次将连接保持打开状态五秒钟,同时为每个查询/命令重新使用该连接。 (上面链接的问题的解决方案在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();
}
ef核心可以使用相同或不同的连接,也可以基于连接池使用。EF核心具有连接和断开的事务处理模式。我认为这可以适合您。在断开连接的场景中存储数据与在连接的场景中存储数据有些不同。在断开连接的情况下,DbContext不知道断开连接的实体,因为在当前DbContext实例的范围之外添加或修改了实体。因此,您需要将断开连接的实体附加到具有适当EntityState的上下文,以便对数据库执行CUD(创建,更新,删除)操作。
下图说明了断开连接情况下的CUD操作:
根据上图,断开连接的实体(DbContext不会跟踪的实体)需要通过适当的EntityState附加到DbContext。例如,新实体的已添加状态,已编辑实体的已修改状态和已删除实体的已删除状态,这将在调用SaveChanges()方法时在数据库中产生INSERT,UPDATE或DELETE命令。
为了在断开连接的情况下使用Entity Framework Core,必须执行以下步骤才能将记录插入,更新或删除到DB表中:
[使用适当的EntityState将实体附加到DbContext,例如添加,修改或删除调用SaveChanges()方法下面的示例演示使用上述步骤将新记录插入数据库:
//Disconnected entity
var std = new Student(){ Name = "Bill" };
using (var context = new SchoolContext())
{
//1. Attach an entity to context with Added EntityState
context.Add<Student>(std);
//or the followings are also valid
// context.Students.Add(std);
// context.Entry<Student>(std).State = EntityState.Added;
// context.Attach<Student>(std);
//2. Calling SaveChanges to insert a new record into Students table
context.SaveChanges();
}
在上面的示例中,std是Student实体的断开连接的实例。 context.Add()方法将Student实体附加到具有添加状态的上下文。 SaveChanges()方法将生成并执行以下INSERT语句:
exec sp_executesql N'SET NOCOUNT ON;https://www.entityframeworktutorial.net/efcore/saving-data-in-disconnected-scenario-in-ef-core.aspx这些是重要的方法。
public DbContext(DbConnection existingConnection, bool contextOwnsConnection)
public DbContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection)
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
}
}
}
https://docs.microsoft.com/en-us/ef/ef6/fundamentals/connection-management?redirectedfrom=MSDN