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()
。
此部分是否只是示例中缺少的部分?还是在处置TransactionScope
或DbContext
时以某种方式自动关闭了连接?
编辑:关闭/处置的调用丢失了。我提出了拉取请求,文档现已更新。
答案 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)) {
....
}