c# - DbContext 的自定义连接打开/关闭

标签 c# entity-framework-core database-connection ef-core-3.1

EF Core 打开和关闭 DbConnection默认情况下为每个查询,除非您传入一个已经打开的连接。

我有 lots of small queries ,所以我不想每次都打开和关闭连接,而是希望每次保持连接打开五秒钟,同时为每个查询/命令重用该连接。 (上面链接的问题的解决方案使连接在 DBContext 的整个生命周期中保持打开状态。)

撇开锁定/并发问题不谈,我在哪里可以在 DbContext 中注入(inject)自定义连接解析/打开逻辑?就像是

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 将记录插入、更新或删除到数据库表中,必须执行以下步骤:

使用适当的 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 和 future 版本中的行为
对于 EF6 和 future 版本,我们采用的方法是,如果调用代码选择通过调用 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

关于c# - DbContext 的自定义连接打开/关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60810685/

相关文章:

mysql - 连接字符串错误。无法找到请求的 .Net Framework 数据提供程序

c# - 如何将 foreach 用于两个不同长度的列表?

c# - 向下拉列表中的列表添加空白选择项

c# - 在具有.Net Core的内存数据库中不向实体集合添加数据

c# - EF Core 中具有自动序列化/反序列化的自定义类型

java - 在 Android Studio 中连接到数据库的基本 URL

php - 获取连接失败 : php_network_getaddresses: getaddrinfo failed: Name or service not known

c# - CRM 2013 通过自定义工作流程获取 CRM URL

c# - 从 HttpContext.User.Claims 中提取值

c# - .Net Core 服务架构、 Entity Framework 和职责