在EF Core 2.1中使用环境事务时,是否需要手动关闭DbConnection?

时间:2018-07-09 06:27:12

标签: c# entity-framework-core transactionscope

EF Core 2.1引入了对环境事务的支持。 sample创建一个新的SqlConnection,手动将其打开并将其传递给DbContext

using (var scope = new TransactionScope(
    TransactionScopeOption.Required, 
    new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }))
{
    var connection = new SqlConnection(connectionString);
    connection.Open();

    try
    {
        // Run raw ADO.NET command in the transaction
        var command = connection.CreateCommand();
        command.CommandText = "DELETE FROM dbo.Blogs";
        command.ExecuteNonQuery();

        // Run an EF Core command in the transaction
        var options = new DbContextOptionsBuilder<BloggingContext>()
            .UseSqlServer(connection)
            .Options;

        using (var context = new BloggingContext(options))
        {
            context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
            context.SaveChanges();
        }

        // Commit transaction if all commands succeed, transaction will auto-rollback
        // when disposed if either commands fails
        scope.Complete();
    }
    catch (System.Exception)
    {
        // TODO: Handle failure
    }
}

虽然没有呼叫connection.Close()

此部分是否只是示例中缺少的部分?还是在处置TransactionScopeDbContext时以某种方式自动关闭了连接?

编辑:关闭/处置的调用丢失了。我提出了拉取请求,文档现已更新。

2 个答案:

答案 0 :(得分:7)

该行为似乎与环境交易无关,但是问题的答案谁拥有传递给DbConnection的{​​{1}}

接受DbContext

EF6 DbContext构造函数具有DbConnection参数,用于明确指定该参数。

但是EF Core呢?接受bool contextOwnsConnection的{​​{1}}方法没有这样的参数。

规则似乎如下,取自UseSqlServer方法UseXyz参数文档:

  

如果连接处于打开状态,则EF将不会打开或关闭连接。如果连接处于关闭状态,则EF将根据需要打开和关闭连接。

我读到“如果未打开通过的连接,EF Core将获得所有权,否则所有权将留给调用方”。

由于该示例在DbConnection之前调用connection,因此我认为您有责任关闭/处置它,因此我认为该示例不正确。

答案 1 :(得分:0)

为了安全起见,请使用以便断开连接。

using(var connection = new SqlConnection(connectionString)) {
   ....
}