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

问题描述 投票:0回答:1

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
c# entity-framework-core database-connection ef-core-3.1
1个回答
0
投票

这是进行交易的标准方法。您可以组合多个查询。

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

© www.soinside.com 2019 - 2024. All rights reserved.