EF Core 2.0中Transaction事务会对DbContext底层创建和关闭数据库连接的行为有所影响...
数据库
我们先在SQL Server数据库中建立一个Book表:
CREATE TABLE [dbo].[Book]([ID] [int] IDENTITY(1,1) NOT NULL,[BookName] [nvarchar](50) NULL,[BookDescription] [nvarchar](50) NULL,[ISBN] [nvarchar](20) NULL,[CreateTime] [datetime] NULL,CONSTRAINT [PK_Book] PRIMARY KEY CLUSTERED ([ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GOALTER TABLE [dbo].[Book] ADD CONSTRAINT [DF_Book_CreateTime] DEFAULT (getdate()) FOR [CreateTime] GO
然后插入如下数据:
INSERT [dbo].[Book] ([BookName], [BookDescription], [ISBN]) VALUES (N'Chinese', N'Chinese', N'0001') GO INSERT [dbo].[Book] ([BookName], [BookDescription], [ISBN]) VALUES (N'English', N'English', N'0002') GO INSERT [dbo].[Book] ([BookName], [BookDescription], [ISBN]) VALUES (N'Japanese', N'Japanese', N'0003') GO INSERT [dbo].[Book] ([BookName], [BookDescription], [ISBN]) VALUES (N'Russian', N'Russian', N'0004') GO INSERT [dbo].[Book] ([BookName], [BookDescription], [ISBN]) VALUES (N'Italian', N'Italian', N'0005') GO
查询Book表的数据,如下图所示:
现在我们使用EF Core将Book表映射到.NET Core控制台项目中的Book实体上,Book实体如下所示:
using System; using System.Collections.Generic;namespace EFCoreDB.Entities {public partial class Book{public int Id { get; set; }public string BookName { get; set; }public string BookDescription { get; set; }public string Isbn { get; set; }public DateTime? CreateTime { get; set; }} }
不使用事务
然后我们在.NET Core控制台项目Program类的Main方法中,使用DbContext(也就是FinanceDigitalToolContext)读取BookName为"Chinese"的Book实体,然后使用DbContext.SaveChanges方法两次更改其BookDescription属性的值,再从数据库中将其查询出来显示,代码如下:
using EFCoreDB.Entities; using System; using System.Linq; using System.Linq.Expressions;namespace EFCoreDB {class Program{static void Main(string[] args){using (FinanceDigitalToolContext dbContext = new FinanceDigitalToolContext()){Expression<Func<Book, bool>> bookExpression = b => b.BookName == "Chinese";//构造查询条件,来查询BookName为Chinese的Bookvar chineseBook = dbContext.Book.First(bookExpression);//获取BookName为Chinese的Book实体chineseBook chineseBook.BookDescription = "This is a Chinese book";//更改chineseBook的BookDescription属性dbContext.SaveChanges();//用DbContext.SaveChanges方法保存更改到数据库 chineseBook.BookDescription = "This is a very good Chinese book";//再次更改chineseBook的BookDescription属性dbContext.SaveChanges();//用DbContext.SaveChanges方法保存更改到数据库 chineseBook = dbContext.Book.First(bookExpression);//重新获取BookName为Chinese的Book实体chineseBook//显示当前chineseBook的当前BookDescription属性值Console.WriteLine(chineseBook.BookName + " book has description: \"" + chineseBook.BookDescription + "\"");}Console.WriteLine("Press key to quit....");Console.ReadLine();}} }
执行上面的代码,我们使用EF Core的日志功能,输出每次DbContext访问数据库时的后台日志信息:
首先在执行
var chineseBook = dbContext.Book.First(bookExpression);//获取BookName为Chinese的Book实体chineseBook
时,EF Core的日志如下所示:
=============================== EF Core log started =============================== Opening connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Opened connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT TOP(1) [b].[ID], [b].[BookDescription], [b].[BookName], [b].[CreateTime], [b].[ISBN] FROM [Book] AS [b] WHERE [b].[BookName] = N'Chinese' =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executed DbCommand (129ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT TOP(1) [b].[ID], [b].[BookDescription], [b].[BookName], [b].[CreateTime], [b].[ISBN] FROM [Book] AS [b] WHERE [b].[BookName] = N'Chinese' =============================== EF Core log finished =============================== =============================== EF Core log started =============================== A data reader was disposed. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Closing connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Closed connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Context 'Book' started tracking 'FinanceDigitalToolContext' entity. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see key values. =============================== EF Core log finished ===============================
从日志中我们可以看出来,dbContext.Book.First(bookExpression)在数据库中开启了一个数据库连接,并使用SQL语句做了查询,然后关闭了数据库连接。
然后在执行下面的代码
chineseBook.BookDescription = "This is a Chinese book";//更改chineseBook的BookDescription属性 dbContext.SaveChanges();//用DbContext.SaveChanges方法保存更改到数据库
时,EF Core的日志如下所示:
=============================== EF Core log started =============================== SaveChanges starting for 'FinanceDigitalToolContext'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== DetectChanges starting for 'FinanceDigitalToolContext'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Unchanged 'Book.BookDescription' detected as changed and will be marked as modified. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see property values. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== An 'Book' entity tracked by 'FinanceDigitalToolContext' changed from 'Unchanged' to 'Modified'. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see key values. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== DetectChanges completed for 'FinanceDigitalToolContext'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Opening connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Opened connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Beginning transaction with isolation level 'ReadCommitted'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executing DbCommand [Parameters=[@p1='?' (DbType = Int32), @p0='?' (Size = 50)], CommandType='Text', CommandTimeout='30'] SET NOCOUNT ON; UPDATE [Book] SET [BookDescription] = @p0 WHERE [ID] = @p1; SELECT @@ROWCOUNT; =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executed DbCommand (86ms) [Parameters=[@p1='?' (DbType = Int32), @p0='?' (Size = 50)], CommandType='Text', CommandTimeout='30'] SET NOCOUNT ON; UPDATE [Book] SET [BookDescription] = @p0 WHERE [ID] = @p1; SELECT @@ROWCOUNT; =============================== EF Core log finished =============================== =============================== EF Core log started =============================== A data reader was disposed. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Committing transaction. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Closing connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Closed connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Disposing transaction. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== An 'Book' entity tracked by 'FinanceDigitalToolContext' changed from 'Modified' to 'Unchanged'. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see key values. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== SaveChanges completed for 'FinanceDigitalToolContext' with 1 entities written to the database. =============================== EF Core log finished ===============================
从日志中我们可以看出来在执行dbContext.SaveChanges方法时,EF Core在数据库中开启了一个数据库连接,并使用SQL语句做了数据库更改,然后关闭了数据库连接。然后chineseBook这个Book实体的EntityState从Modified变为了Unchanged。
然后执行代码
chineseBook.BookDescription = "This is a very good Chinese book";//再次更改chineseBook的BookDescription属性 dbContext.SaveChanges();//用DbContext.SaveChanges方法保存更改到数据库
时,EF Core的日志如下所示:
=============================== EF Core log started =============================== SaveChanges starting for 'FinanceDigitalToolContext'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== DetectChanges starting for 'FinanceDigitalToolContext'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Unchanged 'Book.BookDescription' detected as changed and will be marked as modified. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see property values. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== An 'Book' entity tracked by 'FinanceDigitalToolContext' changed from 'Unchanged' to 'Modified'. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see key values. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== DetectChanges completed for 'FinanceDigitalToolContext'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Opening connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Opened connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Beginning transaction with isolation level 'ReadCommitted'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executing DbCommand [Parameters=[@p1='?' (DbType = Int32), @p0='?' (Size = 50)], CommandType='Text', CommandTimeout='30'] SET NOCOUNT ON; UPDATE [Book] SET [BookDescription] = @p0 WHERE [ID] = @p1; SELECT @@ROWCOUNT; =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executed DbCommand (19ms) [Parameters=[@p1='?' (DbType = Int32), @p0='?' (Size = 50)], CommandType='Text', CommandTimeout='30'] SET NOCOUNT ON; UPDATE [Book] SET [BookDescription] = @p0 WHERE [ID] = @p1; SELECT @@ROWCOUNT; =============================== EF Core log finished =============================== =============================== EF Core log started =============================== A data reader was disposed. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Committing transaction. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Closing connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Closed connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Disposing transaction. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== An 'Book' entity tracked by 'FinanceDigitalToolContext' changed from 'Modified' to 'Unchanged'. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see key values. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== SaveChanges completed for 'FinanceDigitalToolContext' with 1 entities written to the database. =============================== EF Core log finished ===============================
同样从日志中我们可以看出来在执行dbContext.SaveChanges方法时,EF Core在数据库中开启了一个数据库连接,并使用SQL语句做了数据库更改,然后关闭了数据库连接。然后chineseBook这个Book实体的EntityState从Modified变为了Unchanged。
然后执行代码
chineseBook = dbContext.Book.First(bookExpression);//重新获取BookName为Chinese的Book实体chineseBook
时,EF Core的日志如下所示:
=============================== EF Core log started =============================== Opening connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Opened connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT TOP(1) [b].[ID], [b].[BookDescription], [b].[BookName], [b].[CreateTime], [b].[ISBN] FROM [Book] AS [b] WHERE [b].[BookName] = N'Chinese' =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executed DbCommand (21ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT TOP(1) [b].[ID], [b].[BookDescription], [b].[BookName], [b].[CreateTime], [b].[ISBN] FROM [Book] AS [b] WHERE [b].[BookName] = N'Chinese' =============================== EF Core log finished =============================== =============================== EF Core log started =============================== A data reader was disposed. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Closing connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Closed connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished ===============================
从日志中我们可以看出来,dbContext.Book.First(bookExpression)在数据库中还是开启了一个数据库连接,并使用SQL语句做了查询,然后关闭了数据库连接。
总结下来,上面的代码和日志发生的事情如下:
- dbContext.Book.First(bookExpression)开启和关闭了一个数据库连接,查询BookName为Chinese的Book实体chineseBook
- 第一个dbContext.SaveChanges()开启和关闭了一个数据库连接,更改chineseBook的BookDescription属性值"This is a Chinese book"到数据库
- 第二个dbContext.SaveChanges()开启和关闭了一个数据库连接,更改chineseBook的BookDescription属性值"This is a very good Chinese book"到数据库
- dbContext.Book.First(bookExpression)开启和关闭了一个数据库连接,重新查询BookName为Chinese的Book实体chineseBook
所以综上所述DbContext一共开启了和关闭了四个数据库连接。
使用事务
现在我们更改Program类Main方法中的代码,将两次DbContext.SaveChanges方法的调用都放在一个TransactionScope事务范围中,所以现在两次DbContext.SaveChanges方法提交的SQL都会在同一个数据库事务中,代码如下所示:
using EFCoreDB.Entities; using System; using System.Linq; using System.Linq.Expressions; using System.Transactions;namespace EFCoreDB {class Program{static void Main(string[] args){using (FinanceDigitalToolContext dbContext = new FinanceDigitalToolContext()){Expression<Func<Book, bool>> bookExpression = b => b.BookName == "Chinese";//构造查询条件,来查询BookName为Chinese的Bookvar chineseBook = dbContext.Book.First(bookExpression);//获取BookName为Chinese的Book实体chineseBook//使用TransactionScope事务范围来开启一个数据库事务using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew)){chineseBook.BookDescription = "This is a Chinese book";//更改chineseBook的BookDescription属性dbContext.SaveChanges();//用DbContext.SaveChanges方法保存更改到数据库,由于TransactionScope事务范围的存在,所以DbContext.SaveChanges方法提交的SQL语句都存在于TransactionScope的事务当中 chineseBook.BookDescription = "This is a very good Chinese book";//再次更改chineseBook的BookDescription属性dbContext.SaveChanges();//用DbContext.SaveChanges方法保存更改到数据库,由于TransactionScope事务范围的存在,所以DbContext.SaveChanges方法提交的SQL语句都存在于TransactionScope的事务当中 transactionScope.Complete();//提交TransactionScope事务范围中的SQL语句到数据库,数据库事务结束 }chineseBook = dbContext.Book.First(bookExpression);//重新获取BookName为Chinese的Book实体chineseBook//显示当前chineseBook的当前BookDescription属性值Console.WriteLine(chineseBook.BookName + " book has description: \"" + chineseBook.BookDescription + "\"");}Console.WriteLine("Press key to quit....");Console.ReadLine();}} }
执行上面的代码,我们还是使用EF Core的日志功能,输出每次DbContext访问数据库时的后台日志信息:
首先执行
var chineseBook = dbContext.Book.First(bookExpression);//获取BookName为Chinese的Book实体chineseBook
时,EF Core的日志如下所示:
=============================== EF Core log started =============================== Opening connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Opened connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT TOP(1) [b].[ID], [b].[BookDescription], [b].[BookName], [b].[CreateTime], [b].[ISBN] FROM [Book] AS [b] WHERE [b].[BookName] = N'Chinese' =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executed DbCommand (139ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT TOP(1) [b].[ID], [b].[BookDescription], [b].[BookName], [b].[CreateTime], [b].[ISBN] FROM [Book] AS [b] WHERE [b].[BookName] = N'Chinese' =============================== EF Core log finished =============================== =============================== EF Core log started =============================== A data reader was disposed. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Closing connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Closed connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Context 'Book' started tracking 'FinanceDigitalToolContext' entity. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see key values. =============================== EF Core log finished ===============================
从日志中我们可以看出来,dbContext.Book.First(bookExpression)在数据库中开启了一个数据库连接,并使用SQL语句做了查询,然后关闭了数据库连接。
然后执行
using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew)) {
TransactionScope的事务范围开始,此时数据库事务已经开始,EF Core没有输出日志
然后执行
chineseBook.BookDescription = "This is a Chinese book";//更改chineseBook的BookDescription属性 dbContext.SaveChanges();//用DbContext.SaveChanges方法保存更改到数据库,由于TransactionScope事务范围的存在,所以DbContext.SaveChanges方法提交的SQL语句都存在于TransactionScope的事务当中
时,EF Core的日志如下所示:
=============================== EF Core log started =============================== SaveChanges starting for 'FinanceDigitalToolContext'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== DetectChanges starting for 'FinanceDigitalToolContext'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Unchanged 'Book.BookDescription' detected as changed and will be marked as modified. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see property values. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== An 'Book' entity tracked by 'FinanceDigitalToolContext' changed from 'Unchanged' to 'Modified'. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see key values. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== DetectChanges completed for 'FinanceDigitalToolContext'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Opening connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Opened connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Enlisted in an ambient transaction with isolation level 'Serializable'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executing DbCommand [Parameters=[@p1='?' (DbType = Int32), @p0='?' (Size = 50)], CommandType='Text', CommandTimeout='30'] SET NOCOUNT ON; UPDATE [Book] SET [BookDescription] = @p0 WHERE [ID] = @p1; SELECT @@ROWCOUNT; =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executed DbCommand (79ms) [Parameters=[@p1='?' (DbType = Int32), @p0='?' (Size = 50)], CommandType='Text', CommandTimeout='30'] SET NOCOUNT ON; UPDATE [Book] SET [BookDescription] = @p0 WHERE [ID] = @p1; SELECT @@ROWCOUNT; =============================== EF Core log finished =============================== =============================== EF Core log started =============================== A data reader was disposed. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== An 'Book' entity tracked by 'FinanceDigitalToolContext' changed from 'Modified' to 'Unchanged'. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see key values. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== SaveChanges completed for 'FinanceDigitalToolContext' with 1 entities written to the database. =============================== EF Core log finished ===============================
从日志中我们可以看出来在执行dbContext.SaveChanges方法时,EF Core在数据库中开启了一个数据库连接,并使用SQL语句做了数据库更改,但是没有关闭数据库连接。然后chineseBook这个Book实体的EntityState从Modified变为了Unchanged。
然后执行
chineseBook.BookDescription = "This is a very good Chinese book";//再次更改chineseBook的BookDescription属性 dbContext.SaveChanges();//用DbContext.SaveChanges方法保存更改到数据库,由于TransactionScope事务范围的存在,所以DbContext.SaveChanges方法提交的SQL语句都存在于TransactionScope的事务当中
时,EF Core的日志如下所示:
=============================== EF Core log started =============================== SaveChanges starting for 'FinanceDigitalToolContext'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== DetectChanges starting for 'FinanceDigitalToolContext'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Unchanged 'Book.BookDescription' detected as changed and will be marked as modified. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see property values. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== An 'Book' entity tracked by 'FinanceDigitalToolContext' changed from 'Unchanged' to 'Modified'. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see key values. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== DetectChanges completed for 'FinanceDigitalToolContext'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executing DbCommand [Parameters=[@p1='?' (DbType = Int32), @p0='?' (Size = 50)], CommandType='Text', CommandTimeout='30'] SET NOCOUNT ON; UPDATE [Book] SET [BookDescription] = @p0 WHERE [ID] = @p1; SELECT @@ROWCOUNT; =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executed DbCommand (22ms) [Parameters=[@p1='?' (DbType = Int32), @p0='?' (Size = 50)], CommandType='Text', CommandTimeout='30'] SET NOCOUNT ON; UPDATE [Book] SET [BookDescription] = @p0 WHERE [ID] = @p1; SELECT @@ROWCOUNT; =============================== EF Core log finished =============================== =============================== EF Core log started =============================== A data reader was disposed. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== An 'Book' entity tracked by 'FinanceDigitalToolContext' changed from 'Modified' to 'Unchanged'. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see key values. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== SaveChanges completed for 'FinanceDigitalToolContext' with 1 entities written to the database. =============================== EF Core log finished ===============================
从日志中我们可以看出来在执行dbContext.SaveChanges方法时,EF Core在数据库中并没有开启新的数据库连接,而是沿用了上一个DbContext.SaveChanges方法开启的数据库连接来提交SQL语句到数据库。然后chineseBook这个Book实体的EntityState从Modified变为了Unchanged。
然后执行
transactionScope.Complete();//提交TransactionScope事务范围中的SQL语句到数据库,数据库事务结束 }
提交TransactionScope的事务到数据库,此时数据库事务结束,TransactionScope的事务范围也结束,EF Core没有输出日志
然后执行
chineseBook = dbContext.Book.First(bookExpression);//重新获取BookName为Chinese的Book实体chineseBook
时,EF Core的日志如下所示:
=============================== EF Core log started =============================== Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT TOP(1) [b].[ID], [b].[BookDescription], [b].[BookName], [b].[CreateTime], [b].[ISBN] FROM [Book] AS [b] WHERE [b].[BookName] = N'Chinese' =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Executed DbCommand (24ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT TOP(1) [b].[ID], [b].[BookDescription], [b].[BookName], [b].[CreateTime], [b].[ISBN] FROM [Book] AS [b] WHERE [b].[BookName] = N'Chinese' =============================== EF Core log finished =============================== =============================== EF Core log started =============================== A data reader was disposed. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Closing connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished =============================== =============================== EF Core log started =============================== Closed connection to database 'FinanceDigitalTool' on server 'CNGDCAAITSQL01'. =============================== EF Core log finished ===============================
从日志中我们可以看出来,dbContext.Book.First(bookExpression)在数据库中也没有开启新的数据库连接,而是继续沿用了第一个DbContext.SaveChanges方法开启的数据库连接,使用SQL语句做了查询,之后关闭了第一个DbContext.SaveChanges方法开启的数据库连接,所以可以看到第一个DbContext.SaveChanges方法开启的数据库连接,现在才被关闭,这和不使用事务时是完全不一样的。
总结下来,使用事务后的代码和日志发生的事情如下:
- dbContext.Book.First(bookExpression)开启和关闭了一个数据库连接,查询BookName为Chinese的Book实体chineseBook
- using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew)){开启了TransactionScope事务范围,数据库事务开始
- 第一个dbContext.SaveChanges()开启一个数据库连接,但是没有关闭数据库连接,更改chineseBook的BookDescription属性值"This is a Chinese book"到数据库
- 第二个dbContext.SaveChanges()没有开启新的数据库连接,而是沿用了上一个DbContext.SaveChanges方法开启的数据库连接,更改chineseBook的BookDescription属性值"This is a very good Chinese book"到数据库
- transactionScope.Complete()提交TransactionScope事务范围的数据库事务到数据库,数据库事务结束
- }TransactionScope事务范围结束
- dbContext.Book.First(bookExpression)没有开启新的数据库连接,而是沿用了第一个DbContext.SaveChanges方法开启的数据库连接,重新查询BookName为Chinese的Book实体chineseBook,最后关闭了第一个DbContext.SaveChanges方法开启的数据库连接。
所以综上所述DbContext这次一共只开启和关闭了两个数据库连接,并且第二个数据库连接执行了三次数据库操作(两次DbContext.SaveChanges更改数据,一次Book.First查询数据)才被关闭。
由此我们可以看到EF Core在处于事务中时,会优化底层开启和关闭数据库连接的机制,因为EF Core觉得两次DbContext.SaveChanges方法提交的SQL语句既然都在同一个事务中,所以就没有必要每次都开启和关闭一个数据库连接,而是沿用了第一次DbContext.SaveChanges方法开启的数据库连接,所以这和没有使用事务的时候是完全不一样的。
EF Core 2.0中Transaction事务会对DbContext底层创建和关闭数据库连接的行为有所影响...相关推荐
- ASP.NET Core 3.1 Web API和EF Core 5.0 中具有泛型存储库和UoW模式的域驱动设计实现方法
目录 介绍 背景 领域驱动设计 存储库模式 工作单元模式 使用代码 创建空白解决方案和解决方案架构 添加和实现应用程序共享内核库 PageParam.cs 在Entity Framework Core ...
- java EF6,EF Core 2.0和EF6(Entity Framework 6)中配置实体映射关系
1.EF6中通过EntityTypeConfiguration配置实体映射关系代码 public class AccountMap : EntityTypeConfiguration { public ...
- .NET Core 3.0 中的新变化
译者:楚人Leo 译文:http://www.cnblogs.com/leolion/p/10585834.html 原文:https://msdn.microsoft.com/en-us/magaz ...
- Entity Framework 6.3 和 EF Core 3.0 路线图
尽管脱离了 .NET Core 发布循环,但是 EF Core 正在开发其 3.0 路线图.除此之外,还对原来的 Entity Framework 进行了一些重要的变更. 更多服务器端的查询 将 LI ...
- EF Core 3.0查询
随着.NET Core 3.0的发布,EF Core 3.0也随之正式发布,关于这一块最近一段时间也没太多去关注,陆续会去对比之前版本有什么变化没有,本节我们来看下两个查询. 分组 我们知道在EF C ...
- EF Core 2.0使用MsSql/Mysql实现DB First和Code First
环境 Visual Studio 2017 最新版本的.NET Core 2.0 SDK 最新版本的 Windows PowerShell 开始搭建 1.在 Visual Studio 2017 中创 ...
- ASP.NET Core 开发-Entity Framework (EF) Core 1.0 Database First
ASP.NET Core 开发-Entity Framework Core 1.0 Database First,ASP.NET Core 1.0 EF Core操作数据库. Entity Frame ...
- ASP.NET Core 1.0中的管道-中间件模式
ASP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middleware)的方式注册在管道中.显而易见这样的设计非常松耦合 ...
- .NET Core 3.0中的新功能和增强功能
目录 介绍 主要变化 Windows桌面支持 本机可执行文件 JSON API 更好的垃圾收集器 性能改进 Docker增强 ARM64支持 物联网支持 密码学 与.NET Core 2.2的AP ...
最新文章
- java数据类型_java 数据类型
- 格式android id,android 获取APP的唯一标识applicationId的实例
- C++字符串函数与C字符串函数比较
- 简单的for()循环使用方式foreach
- python 登录接口_使用python编写一个登录接口
- 深度学习-tensorflow1.x- 理解 经过softmax_cross_entropy_with_logit后 随机梯度下降的过程
- react-router-dom系列之-codesandbox
- gstreamer的rtsp推流(笔记)
- c语言链表死循环,单项循环链表解决Joseph 问题,死循环了,求帮忙
- Android学习JNI,使用JNI实现字符串加密
- 查歌词php,php krc歌词解析
- 独孤九剑-第六式 成长体验
- 笔记本ubuntu安装xen之殇
- 关于Navicat 连接 RDS数据库
- 陪你云sdk用户指南
- Button点击事件
- 最简真分数 【辗转相除法】
- 串口和以太网口的区别
- 用Python 爬《蜘蛛侠:英雄远征》猫眼评论并分析
- 集成学习:lightGBM(一)
热门文章
- Android Studio新建项目出错如何解决
- java中static修饰函数_详解java中static关键词的作用
- 二十年后我发明了保姆机器人作文_小学生作文“二十年后的我”走红,老师看完气愤,让学生站着听课...
- 学python lesson3
- python 极速后台开发框架_基于FastAdmin快速搭建后台管理系统
- 取rtsp流数据_SDP在RTSP、国标GB28181、WebRTC中的实践
- python发送图片邮件exchangelib_python基于exchange函数发送邮件过程详解
- vue学习代码理解v-for数组遍历和对象遍历以及事件处理
- easyexcel 导出设置标题_GitHub - niaobulashi/easy-excel: excel实现导入导出配置型通用方法项目...
- 微擎自动回复 加粉丝名_如何一天加100个精准粉丝?蒋老师告诉你系统的套路和方法...