数据库操作预计会影响1行,但实际上影响了0行

时间:2018-04-11 17:51:05

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

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

首先我尝试了以下代码。

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   行(S)。自实体以来,数据可能已被修改或删除   加载。请参阅http://go.microsoft.com/fwlink/?LinkId=527962   有关理解和处理乐观并发的信息   异常。

堆栈跟踪:

  

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

     

INFO 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:\回购\ MyProjectVenues \ ASPNET核\ SRC \ MyCompany.MyProject.Application \ AdditionalMasterData \测试\ TestsAppService.cs:线   205   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   MyCompany.MyProject.AdditionalMasterData.Tests.TestsAppService.d__6.MoveNext()   在   C:\回购\ MyProjectVenues \ ASPNET核\ SRC \ MyCompany.MyProject.Application \ AdditionalMasterData \测试\ TestsAppService.cs:线   170   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__12.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__10.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at   Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext   上下文)   Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(州及放大器;   接下来,范围&范围,对象& state,Boolean& isCompleted)at   Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__14.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__23.MoveNext()

更新

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

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

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

9 个答案:

答案 0 :(得分:2)

确保在您的存储库函数InsertAsync中不要调用AddAsync,除非您使用的是Microsoft.EntityFrameworkCore.Metadata.SqlServerValueGenerationStrategy.SequenceHiLo生成器。正如文档中所记录的那样。 AddAsync

答案 1 :(得分:1)

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

        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;
            }

        }
    }

答案 2 :(得分:0)

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

答案 3 :(得分:0)

我有类似的问题。我使用了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)]

答案 4 :(得分:0)

对于我来说,当我尝试将 Update()方法传递给数据库中不存在的实体时,会引起问题。

答案 5 :(得分:0)

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

enter image description here

答案 6 :(得分:0)

确保生成的SQL查询实际上可以到达目标行。 在我的情况下,查询看起来像这样:

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

但是'ConcurrencyStamp'包含一个非空值,因此没有任何更新。

答案 7 :(得分:0)

如果有人带着和我一样的背景来到这里,当我有一个 DateTime 列作为 PK 并且这个列被配置为 {{1 }}。

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

.HasDefaultValueSql("getdate()")

我实际上还没有修复那个错误,但是我能够通过在 C# 上设置 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' 列的值来使它工作,而不是期望数据库这样做。< /p>

答案 8 :(得分:0)

和其他用户一样,我的问题是由 SQL Server 中的 rowversion(在我们的模型中称为 byte[] ChangeVersion)引起的。实体框架附加 where ChangeVersion = ... 作为 SQL 查询的一部分。但是,用于 ChangeVersion 的实体框架值是默认值 (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();