【问题标题】:How to create a total new connetion to Mysql in c#?如何在 C# 中创建与 Mysql 的全新连接?
【发布时间】:2017-10-30 06:12:17
【问题描述】:

在存储过程中,我创建了一个临时表来存储结果,我知道如果有超过1次调用此存储过程在1个连接中(因为它只使用 1 个临时表名 => 无法区分哪个属于哪个请求)。

BEGIN
  CREATE TEMPORARY TABLE IF NOT EXISTS TempTable (RowOrdinal INT DEFAULT 0);
  INSERT INTO TempTable(RowOrdinal) VALUES (1);
  SELECT COUNT(*) FROM TempTable;
END $$

可以看到,在同一个连接中,每次调用这个store,TempTable都会多增加1行。

在我的 C# 项目中,我测试了几种方法来建立新的 MySQL 连接以调用存储过程。

  1. 创建新的 dbcontext(在实体框架中),然后使用

    public int CallStoreFunction()
    {
       return result = dbcontext.Database.SqlQuery<int>("CALL store_proc()");
    }
    
  2. 通过创建一个新实例来创建连接:

    public int CallStoreFunction()
    {
      var result = 0;
      using(var connection  = new MySqlConnection(connectionString))
      {
        connection.Open();
        var command = new MySqlCommand("CALL store_proc()", connection) 
        result =  int.Parse(command.ExecuteScalar().ToString());
        connection.Close();
      }
      return result;
    }
    

每一种方式,我都调用了这个函数四次,结果都是 4(这意味着每次调用 store 仍然在同一个连接中)

看起来 C# 只是创建一个新的会话/事务,而不是一个新的连接,无论我使用哪种方法。我想知道每次我向这家商店发出请求时,它是一种创建与数据库的完全不同连接的方法吗? 提前致谢!

【问题讨论】:

  • 当您创建临时表时,您使用的是CREATE TEMPORARY TABLE 语法,对吗? EF 和 ADO 都使用连接池,因此如果连接已被释放(您正在使用 Close + Dispose 执行此操作),您通常会从池中返回相同的连接。 TEMPORARY 表应该是每个会话的,所以即使使用连接池,它们也应该是唯一的。

标签: c# mysql entity-framework stored-procedures dbcontext


【解决方案1】:

ADO.NET 管理连接池中的连接。当您调用 Open 连接时,它会在池中寻找可用的连接。如果它可用,它将被返回(不要创建新连接)。当你调用 Close 时,它会以活动状态返回到池中(它已准备好被重用)。

因此,您的代码仍在使用相同的连接和相同的临时表。如果你想创建一个完全连接,你应该先清除池。 ADO.NET 支持 ClearAllPools 和 ClearPool,对于 MySQL,它看起来像:

MySql.Data.MySqlClient.MySqlConnection.ClearPool(connection);

例如:

        var result = 0;

        var connectionString = ConfigurationManager.ConnectionStrings["your_connection"].ConnectionString;
        using (var connection = new MySqlConnection(connectionString))
        {
            connection.Open();
            var command = new MySqlCommand("CALL new_procedure()", connection);
            result = int.Parse(command.ExecuteScalar().ToString());
            MySql.Data.MySqlClient.MySqlConnection.ClearPool(connection);
            connection.Close();                 
        }

        using (var connection = new MySqlConnection(connectionString))
        {
            connection.Open();
            var command = new MySqlCommand("CALL new_procedure()", connection);
            result = int.Parse(command.ExecuteScalar().ToString());
            connection.Close();                
        }
        using (var connection = new MySqlConnection(connectionString))
        {
            connection.Open();
            var command = new MySqlCommand("CALL new_procedure()", connection);
            result = int.Parse(command.ExecuteScalar().ToString());
            connection.Close();                
        }    

结果 = 1,结果 = 2

参考:https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-connection-pooling

【讨论】:

    猜你喜欢
    • 2017-07-24
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-23
    相关资源
    最近更新 更多