实体框架SaveChanges如何工作?

时间:2018-05-01 06:04:21

标签: c# entity-framework

我尝试了解EF如何通过代码中的对象操作创建数据库请求。我的测试场景很简单:

using(var context = new Context())
{
var entity = context.Entities.First();
entity.A = "TST";
entity.B = "WrongValue";
context.SaveChanges();
}

我的想法是测试,EF如何处理交易。 使用正确的值更改A并使用错误的值更改B(不存在的FK) 我跟踪SQL Server DB中发生的事情。 我执行代码并没有任何更改DB,这是预期的。 奇怪的是,有两个独立的SQL请求,我不明白EF如何还原第一个。

1 个答案:

答案 0 :(得分:4)

Entity FrameworkEntityFramework core代码都是开源代码。您可以在

查看代码
  1. 实体框架 - Link
  2. 实体框架核心 - Link
  3. 如果您看到Save method的内部代码(粘贴下面的代码快照),那么您可以在内部验证它是否在未提供外部事务时创建事务。

        internal int SaveChangesInternal(SaveOptions options, bool executeInExistingTransaction)
        {
            AsyncMonitor.EnsureNotEntered();
    
            PrepareToSaveChanges(options);
    
            var entriesAffected = 0;
    
            // if there are no changes to save, perform fast exit to avoid interacting with or starting of new transactions
            if (ObjectStateManager.HasChanges())
            {
                if (executeInExistingTransaction)
                {
                    entriesAffected = SaveChangesToStore(options, null, startLocalTransaction: false);
                }
                else
                {
                    var executionStrategy = DbProviderServices.GetExecutionStrategy(Connection, MetadataWorkspace);
                    entriesAffected = executionStrategy.Execute(
                        () => SaveChangesToStore(options, executionStrategy, startLocalTransaction: true));
                }
            }
    
            ObjectStateManager.AssertAllForeignKeyIndexEntriesAreValid();
            return entriesAffected;
        }
    

    因此,您的下面的代码将在内部包装在您可以在SQL事件探查器中验证的事务中。

    using(var context = new Context())
    {
    var entity = context.Entities.First();
    entity.A = "TST";
    entity.B = "WrongValue";
    context.SaveChanges();
    }
    

    但是,SQL事件探查器不会开始记录事务,因此您需要在跟踪设置中配置它。请参阅下面的SQL profiler新Trace设置的屏幕截图,在这里,我检查了Show All events。之后显示Transaction类别。您可以订阅Begin TranCommit TranRollback Tran事件来验证事务语句。当您运行场景时,您可以看到应记录Begin和Rollback。 enter image description here