【问题标题】:Database operation expected to affect 1 row(s) but actually affected 0 row(s)数据库操作预计会影响 1 行,但实际上会影响 0 行
【发布时间】:2018-09-21 17:18:23
【问题描述】:

我试图在两个表中插入记录,但出现异常。你能帮我解决这个问题吗?

首先我尝试了下面的代码。

await _testRepository.InsertAsync(test);
await _xyzRepository.InsertAsync(xyz);

然后我尝试了这段代码,但没有什么对我有用。

try
{
   var test = new Test();

   using (var uow = _unitOfWorkManager.Begin(TransactionScopeOption.RequiresNew))
   {
      int? tenantId = _unitOfWorkManager.Current.GetTenantId();
      using (_unitOfWorkManager.Current.SetTenantId(tenantId))
      {
         await _testRepository.InsertAsync(test);

         var xyz = new XYZ();
         await _xyzRepository.InsertAsync(xyz);
         await _unitOfWorkManager.Current.SaveChangesAsync();
         await uow.CompleteAsync();
      }
   }
}
catch (Exception ex)
{
   throw new UserFriendlyException(ex.Message);
}

例外

消息:

数据库操作预计会影响 1 行,但实际上会影响 0 行。数据可能已被修改或删除,因为实体 加载。见http://go.microsoft.com/fwlink/?LinkId=527962 有关理解和处理乐观并发的信息 例外。

堆栈跟踪:

在 Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ThrowAggregateUpdateConcurrencyException(Int32 commandIndex,Int32 预期行影响,Int32 行影响)在 Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.d__4.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.d__2.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.d__32.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.d__10.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerExecutionStrategy.d__7`2.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.d__61.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.d__59.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Microsoft.EntityFrameworkCore.DbContext.d__48.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Abp.EntityFrameworkCore.AbpDbContext.d__49.MoveNext() 在 D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\AbpDbContext.cs:line 214

信息 2018-04-11 13:59:53,439 [3] ore.Mvc.Internal.ControllerActionInvoker - 执行动作方法 MyCompany.MyProject.AdditionalMasterData.Tests.TestsAppService.CreateOrEdit (MyCompany.MyProject.Application) 带参数 ([CreateOrEditTestDto ]) - ModelState 有效 WARN 2018-04-11 14:01:48,396 [4] Mvc.ExceptionHandling.AbpExceptionFilter - 需要数据库操作 影响 1 行,但实际上影响了 0 行。数据可能已经 自加载实体后修改或删除。看 http://go.microsoft.com/fwlink/?LinkId=527962 获取有关信息 理解和处理乐观并发异常。 Abp.UI.UserFriendlyException: 数据库操作预计会影响 1 行,但实际上影响了 0 行。数据可能已被修改或 自加载实体后删除。看 http://go.microsoft.com/fwlink/?LinkId=527962 获取有关信息 理解和处理乐观并发异常。在 MyCompany.MyProject.AdditionalMasterData.Tests.TestsAppService.d__7.MoveNext() 在 C:\Repo\MyProjectVenues\aspnet-core\src\MyCompany.MyProject.Application\AdditionalMasterData\Tests\TestsAppService.cs:line 205 --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 MyCompany.MyProject.AdditionalMasterData.Tests.TestsAppService.d__6.MoveNext() 在 C:\Repo\MyProjectVenues\aspnet-core\src\MyCompany.MyProject.Application\AdditionalMasterData\Tests\TestsAppService.cs:line 170 --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__12.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__10.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext 上下文)在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(状态& next, Scope& 范围, Object& 状态, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__14.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__23.MoveNext()

更新

我找到了问题的根本原因。

所以基本上我在 Entity2 上有一个插入触发器,当我在这个触发器中评论了查询,然后它工作正常。

此触发器中大约有 10 个查询,很难知道是哪一个导致了问题。那么能否请您告诉我如何调试此触发器?

【问题讨论】:

  • 此问题中的所有代码都掩盖了实体框架中实际发生的情况。最后它变成了一个完全不同的问题。

标签: c# asp.net-core ef-code-first entity-framework-core aspnetboilerplate


【解决方案1】:

我遇到了类似的问题。我使用了 EF Core。我的代码的以下更改帮助了我。

context.Entry(user).State = EntityState.Added; // added row
this.context.Users.Add(user);
this.context.SaveChanges();

UPD:抱歉,问题已通过为 User.Id 添加 Identity 属性解决

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

【讨论】:

    【解决方案2】:

    确保在您的存储库函数 InsertAsync 中您没有调用 AddAsync,除非您使用的是 Microsoft.EntityFrameworkCore.Metadata.SqlServerValueGenerationStrategy.SequenceHiLo 生成器。如文档中所述。 AddAsync

    【讨论】:

      【解决方案3】:

      我的代码的问题是,我设置了primary key value for tables explicitly,它是not db generated,但efcore 不知道这一点.. 所以最后我需要写(ValueGeneratedNever

              protected override void OnModelCreating(ModelBuilder modelBuilder)
              {
                  base.OnModelCreating(modelBuilder);
      
                  //TODO: on add any entity add here the same
                  modelBuilder.Entity<AdminUser>().Property(e => e.AdminUserId).ValueGeneratedNever();
                  modelBuilder.Entity<AdminUserLogInLog>().Property(e => e.AdminUserLogInLogId).ValueGeneratedNever();
                  ...........
               }
      

      所有表的通用方法

          protected override void OnModelCreating(ModelBuilder modelBuilder)
          {
              base.OnModelCreating(modelBuilder);
              
              foreach (var item in modelBuilder.Model.GetEntityTypes())
              {
                  var p = item.FindPrimaryKey().Properties.FirstOrDefault(i=>i.ValueGenerated!=Microsoft.EntityFrameworkCore.Metadata.ValueGenerated.Never);
                  if (p!=null)
                  {
                      p.ValueGenerated = Microsoft.EntityFrameworkCore.Metadata.ValueGenerated.Never;
                  }
      
              }
          }
      

      【讨论】:

        【解决方案4】:

        就我而言,当我尝试将数据库中不存在的实体传递给 Update() 方法时导致的问题。

        【讨论】:

          【解决方案5】:

          确保生成的 SQL 查询实际上可以到达目标行。 就我而言,查询如下所示:

          UPDATE [Users] SET .....
          WHERE [Id] = @p34 AND [ConcurrencyStamp] = null;
          

          但 'ConcurrencyStamp' 包含一个非空值,因此没有什么可更新的。

          【讨论】:

            【解决方案6】:

            我发现这可能是主键上的绑定问题。检查您的查询字符串以确保所有内容在您的视图和更新操作中都正确绑定。 (确保查询字符串值没有覆盖输入值)。

            【讨论】:

              【解决方案7】:

              您还可以检查您的表是否启用了 PK(主键)身份选项。

              【讨论】:

                【解决方案8】:

                如果有人以与我相同的背景到达这里,当我将 DateTime 列作为 PK 并且此列配置为 .HasDefaultValueSql("getdate()") 时,我会遇到 Add 错误。

                我必须使用分析器来查看 EFCore 正在为此列发送 NULL 值并尝试与新生成的日期进行比较:

                exec sp_executesql N'SET NOCOUNT ON;
                DECLARE @inserted0 TABLE ([Current_Nbr] nvarchar(450), [Db_Date] datetime2, [_Position] [int]);
                MERGE [Current_Moves] USING (
                VALUES (@p0, @p1, @p2, @p3, 0)) AS i ([Current_Nbr], [Despatch_Number], [Current_Loc], [Operator], _Position) ON 1=0
                WHEN NOT MATCHED THEN
                INSERT ([Current_Nbr], [Despatch_Number], [Current_Loc], [Operator])
                VALUES (i.[Current_Nbr], i.[Despatch_Number], i.[Current_Loc], i.[Operator])
                OUTPUT INSERTED.[Current_Nbr], INSERTED.[Db_Date], i._Position
                INTO @inserted0;
                
                SELECT [t].[Db_Date] FROM [Current_Moves] t
                INNER JOIN @inserted0 i ON ([t].[Current_Nbr] = [i].[Current_Nbr]) AND ([t].[Db_Date] = [i].[Db_Date])
                ORDER BY [i].[_Position];
                
                ',
                N'@p0 nvarchar(450),@p1 nvarchar(4000),@p2 nvarchar(4000),@p3 nvarchar(4000)',
                @p0=N'AAAAA',@p1=NULL,@p2=N'LOC_123',@p3=N'xxxxx'
                

                我实际上并没有修复 那个 错误,但我能够通过在 C# 上设置 DateTime 列的值来使其工作,而不是期望数据库这样做。

                【讨论】:

                  【解决方案9】:

                  和其他用户一样,我的问题是由 SQL Server 中的 rowversion 引起的(在我们的模型中称为 byte[] ChangeVersion)。实体框架在 SQL 查询中附加了 where ChangeVersion = ...。但是,用于 ChangeVersion 的值 Entity Framework 是默认值 (0)。实体框架已决定不应使用以下内容从数据库中填充 ChangeVersion 属性:

                  var deleteCompany = dbContext.Company.FirstOrDefault(x => x.CompanyId == cmvm.DeleteCompanyId.Value);
                  // at this point, deleteCompany.ChangeVersion = 0 but other fields are populated.
                  dbContext.Company.Remove(deleteCompany);
                  dbContext.SaveChanges(); // error expected 1 row but 0 affected
                  

                  模型构建器的样子

                  entity.Property(e => e.ChangeVersion).HasColumnName("ChangeVersion")
                                      .IsRequired()
                                      .IsRowVersion();
                  

                  将原始查找查询更改为 AsNoTracking 可解决此问题。这工作没有错误

                  // Call this AsNoTracking. Otherwise Entity Frameworks throws out the ChangeVersion for some reason.
                  var deleteCompany = dbContext.Company.AsNoTracking().FirstOrDefault(x => x.CompanyId == cmvm.DeleteCompanyId.Value);
                  dbContext.Entry(deleteCompany).State = EntityState.Deleted;
                  dbContext.Company.Remove(deleteCompany);
                  dbContext.SaveChanges();
                  

                  【讨论】:

                  • 出于某种原因, -- 深入了解这一点很重要,因为这不是标准的 EF 行为。代码中的某些内容必须使 ChangeVersion 成为 0。我不认为一个不清楚的错误应该导致答案。 “似乎是由引起的”和“似乎可以解决的”太试探而无济于事。
                  【解决方案10】:

                  我在使用 SQLite 数据库时遇到了同样的问题,但使用的是更新而不是插入。解决方案是调用 SaveChangesAsync 而不是 SaveChanges。

                  【讨论】:

                  • 为什么这能解决问题?
                  • 我发现这看起来确实是我从 UI 中解决了问题,但在检查数据库后,我实际上并没有在那里写入数据。对我来说,原因是我在一个对象上显式设置了 Id,然后我尝试将其添加(插入)到数据库中,但是该对象的模型无论如何都有一个自生成的 Id:([Key] [DatabaseGenerated(DatabaseGeneratedOption. Identity)] public Guid Id { get; set; }) 所以 EF 认为“他们给了我一个 ID,所以这一定是更新而不是插入”,因此出现了错误。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2022-08-04
                  相关资源
                  最近更新 更多