为什么我需要手动打开这个 .NET Core 数据库连接,而通常 Dapper 会自动打开它?

我正在尝试使用 async/await 将一些记录插入到数据库中.如果我不手动打开连接,我会收到 Exception.如果我添加一些代码来打开连接,那么一切正常.

这是当前代码(抛出异常):

using (var connection = new SqlConnection(ConnectionString)){var tasks = new List();soldUrls.ForEach(url => tasks.Add(InsertUrlAsync(connection, url)));rentUrls.ForEach(url => tasks.Add(InsertUrlAsync(connection, url)));等待 Task.WhenAll(tasks);}...私有异步任务 InsertUrlAsync(IDbConnection 连接,字符串 url){const string query = "INSERT INTO ..";return await connection.ExecuteAsync(query, new { .. });}

异常:

<块引用>

消息:System.InvalidOperationException:操作无效.连接已关闭.

但是当我将代码更改为以下内容时,它起作用了:

var tasks = new List();等待 connection.OpenAsync();sellUrls.ForEach(....) .. 等等...

类似的问题:

  • Task.WhenAll,连接正在关闭
  • SqlConnection 在 using 语句中意外关闭

解决方案

Dapper 为您打开连接;但它也会在工作完成后关闭它.

现在,您正在使用一个连接运行两个独立的async 任务.

<块引用>

soldUrls.ForEach(url => tasks.Add(InsertUrlAsync(connection, url)));rentUrls.ForEach(url => tasks.Add(InsertUrlAsync(connection, url)));

两个任务同时运行.当一项任务的工作完成时,它关闭连接.但是其他任务仍在运行,它不再有权访问打开的连接,因此出现了您提到的异常.

如您所说,如果您自己打开连接,Dapper 不会关闭它,一切正常.

顺便说一下,在并发使用连接实例时,可能会出现意想不到的问题.请参阅此问题了解更多详情.

I'm trying to use async/await to insert a number of records into a database. If I don't manually open the connection, I get an Exception. If I add some code to open the connection, then everything works ok.

Here's the current code (which throws an Exception):

using (var connection = new SqlConnection(ConnectionString))
{
    var tasks = new List<Task>();
    soldUrls.ForEach(url => tasks.Add(InsertUrlAsync(connection, url))); 
    rentUrls.ForEach(url => tasks.Add(InsertUrlAsync(connection, url)));
    await Task.WhenAll(tasks);
}

...

private async Task InsertUrlAsync(IDbConnection connection, string url)
{
    const string query = "INSERT INTO ..";
    return await connection.ExecuteAsync(query, new { .. });
}

the exception:

Message: System.InvalidOperationException : Invalid operation. The connection is closed.

but when I change the code to the following, it works:

var tasks = new List<Task>();
await connection.OpenAsync();
soldUrls.ForEach(....) .. etc ... 

Similar SO questions:

  • Task.WhenAll, connection is closing
  • SqlConnection closes unexpectedly inside using statement

解决方案

Dapper opens the connection for you; but it also closes it when work is done.

Now, you are running two independent async tasks using one single connection.

soldUrls.ForEach(url => tasks.Add(InsertUrlAsync(connection, url))); 
rentUrls.ForEach(url => tasks.Add(InsertUrlAsync(connection, url)));

Both the tasks are running simultaneously. When work of one task finish, it closes the connection. But other task is still running which does not have access to open connection anymore and hence the exception you mentioned in question.

As you said, if you open the connection yourself, Dapper does not close it and everything just works fine.

By the way, while using connection instance concurrently, there may be unexpected issues. Please refer to this question for more details.

相关文章