C# 零星的;“当前不支持多个同时连接”;

C# 零星的;“当前不支持多个同时连接”;,c#,asp.net,mysql,entity-framework,C#,Asp.net,Mysql,Entity Framework,我有一个使用实体框架和MySQL数据库的ASP.NET web应用程序。我正在做一些关于动态表的工作,所以我求助于编写原始SQL。我需要添加一些东西来保证代码的线程安全吗?对于我的系统中的每个用户,都可以并且将非常频繁地调用此代码。它总是通过调用信息\u SCHEMA来发现错误 以下是我在尝试调用AddMessageAction时经常收到的错误(但不是每次): 以及守则: public static class UserActionModel { private const string da

我有一个使用实体框架和MySQL数据库的ASP.NET web应用程序。我正在做一些关于动态表的工作,所以我求助于编写原始SQL。我需要添加一些东西来保证代码的线程安全吗?对于我的系统中的每个用户,都可以并且将非常频繁地调用此代码。它总是通过调用
信息\u SCHEMA
来发现错误

以下是我在尝试调用
AddMessageAction
时经常收到的错误(但不是每次):

以及守则:

public static class UserActionModel
{

private const string databaseName = "chat";

public static string CheckTableExists(long _userId)
{
    string tableName = null;
    List<long> tableExists;

    try
    {
        string date = DateTime.Now.ToUniversalTime().Year.ToString() + DateTime.Now.ToUniversalTime().Month.ToString("D2") + DateTime.Now.ToUniversalTime().Day.ToString("D2");

        tableName = "user_actions_" + date + "_" + _userId;

        string sql = "SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_NAME = '" + tableName + "' AND TABLE_SCHEMA = 'archive'";

        using (var readContext = new ArchiveConnector())
        {
            tableExists = readContext.Database.SqlQuery<long>(sql).ToList();
            readContext.Database.Connection.Close();
        }

        if (tableExists.Any(tableExist => tableExist == 0))
        {
            sql = "CREATE TABLE IF NOT EXISTS `" + tableName + "` ("
                  + "`id` bigint(20) NOT NULL AUTO_INCREMENT, "
                  + "`user_id` bigint(20) NOT NULL, "
                  + "`user_device_id` bigint(20) NOT NULL, "
                  + "`coordinate_address_id` bigint(20) NOT NULL, "
                  + "`message_id` bigint(20) DEFAULT NULL, "
                  + "`created` datetime NOT NULL, "
                  + "PRIMARY KEY (`id`), "
                  + "KEY `user_id` (`user_id`), "
                  + "KEY `user_device_id` (`user_device_id`), "
                  + "KEY `coordinate_address_id` (`coordinate_address_id`), "
                  + "KEY `message_id` (`message_id`); "

            using (var writeContext = new ArchiveConnector())
            {
                writeContext.Database.ExecuteSqlCommand(sql);
                writeContext.SaveChanges();
                writeContext.Database.Connection.Close();

            }
        }
    }
    catch (Exception ex)
    {
        Logger.LogMessage("UserActionModel:CheckTableExists ex: " + ex.Message);

        if (ex.InnerException != null)
            Logger.LogMessage("UserActionModel:CheckTableExists inner ex: " + ex.InnerException);

        tableName = null;
    }

    return tableName;
}

public static void AddMessageAction(long _messageId, long _userId, long _userDeviceId, long _coordinateAddressId)
{
    try
    {
        string tableName = CheckTableExists(_userId);

        if (String.IsNullOrEmpty(tableName)) return;

        using (var dataContext = new ArchiveConnector())
        {
            string sql = "INSERT INTO " + tableName + " "
                + "(user_id, user_device_id, coordinate_address_id, message_id, created) "
                + "VALUES "
                + "(" + _userId + ", " + _userDeviceId + ", " + _coordinateAddressId + ", " + _messageId + ", NOW());";

            dataContext.Database.ExecuteSqlCommand(sql);
            dataContext.SaveChanges();
        }
    }
    catch (Exception ex)
    {
        Logger.LogMessage("UserActionModel:AddMessageAction (" + _messageId + ") ex: " + ex.Message);
    }
}
}    
公共静态类UserActionModel
{
private const string databaseName=“chat”;
公共静态字符串CheckTableExists(长\u用户ID)
{
字符串tableName=null;
列表表存在;
尝试
{
字符串日期=DateTime.Now.ToUniversalTime().Year.ToString()+DateTime.Now.ToUniversalTime().Month.ToString(“D2”)+DateTime.Now.ToUniversalTime().Day.ToString(“D2”);
tableName=“user\u actions\u”+日期+“\u”+\u用户ID;
string sql=“从信息_schema.TABLES中选择COUNT(*),其中TABLE_NAME='“+tableName+”,TABLE_schema='archive';
使用(var readContext=new ArchiveConnector())
{
tableExists=readContext.Database.SqlQuery(sql.ToList();
readContext.Database.Connection.Close();
}
if(tableExists.Any(tableExist=>tableExist==0))
{
sql=“创建不存在的表”`+tableName+`(“
+`id`bigint(20)非空自动增量,'
+'user_id`bigint(20)不为空,'
+“`user\u device\u id`bigint(20)不为空,”
+“`coordination\u address\u id`bigint(20)不为空,”
+“`message_id`bigint(20)默认为空,”
+“`created`datetime不为空,”
+“主键(`id`),”
+“键'user\u id'('user\u id'),”
+“键'user\u device\u id'('user\u device\u id'),”
+“键'coordinate\u address\u id'('coordinate\u address\u id'),”
+“键`message\u id`(`message\u id`);”
使用(var writeContext=new ArchiveConnector())
{
writeContext.Database.ExecuteSqlCommand(sql);
writeContext.SaveChanges();
writeContext.Database.Connection.Close();
}
}
}
捕获(例外情况除外)
{
Logger.LogMessage(“UserActionModel:CheckTableExists ex:+ex.Message”);
if(例如InnerException!=null)
LogMessage(“UserActionModel:CheckTableExists内部ex:+ex.InnerException”);
tableName=null;
}
返回表名;
}
公共静态void AddMessageAction(长消息ID、长用户ID、长用户设备ID、长协调ID)
{
尝试
{
字符串tableName=CheckTableExists(_userId);
if(String.IsNullOrEmpty(tableName))返回;
使用(var dataContext=new ArchiveConnector())
{
string sql=“插入到”+tableName+“”
+(用户标识、用户设备标识、坐标地址标识、消息标识,已创建)
+“价值观”
+“(“++u userId+”、“++u userDeviceId+”、“++u coordinatedDressId+”、“++u messageId+”,NOW());”;
dataContext.Database.ExecuteSqlCommand(sql);
dataContext.SaveChanges();
}
}
捕获(例外情况除外)
{
LogMessage(“UserActionModel:AddMessageAction(“+_messageId+”)ex:“+ex.Message”);
}
}
}    
从我的web.config连接字符串中删除
persist security info=True
没有任何区别(我读到这是一个可能的解决方案)

UDPATE:从连接器6.6.4更新为6.6.5。无更改。
UDPATE:已从连接器6.6.5更新为6.7.1 Alpha。无更改。

ArchiveConnector
Dispose
方法未关闭其MySQL连接。当您:

using (var writeContext = new ArchiveConnector())
连接位于:

using (var readContext = new ArchiveConnector())
仍处于打开状态,并且MySQL不支持同一事务上的多个连接。请确保在
ArchiveConnector.Dispose()
上关闭了您的连接


祝你好运。

我正在调用我的
AddMessageAction()
在另一个连接器上使用从
内部执行。不要这样做。

我认为
使用
块的结尾会自动处理所有Dispose调用??从MSDN:
可以在using语句中创建一个实例,以确保在using语句退出时对对象调用Dispose。
using (var readContext = new ArchiveConnector())