【问题标题】:EF Core Fix issues After SaveChanges FailureSaveChanges 失败后的 EF Core 修复问题
【发布时间】:2023-03-13 20:22:01
【问题描述】:

我有这段代码(在 Asp.net 核心中),我尝试将对象列表添加到 DB:

try
   {
      await _context.AddRangeAsync(mhUserAtts);
      await _context.SaveChangesAsync();
   }
catch()
   {

   }

当某些对象与 DB 冲突时,如何将它们从列表中删除? 然后返回以将其余部分保存到 DB。

【问题讨论】:

  • 如果你想要完整的数据库写入,你应该添加你的实体并保存每个对象的更改
  • 我更喜欢将AddRangeAsync 用作单行代码以及它的性能优势
  • 如果您使用AddRange,如果您的任何实体在写入和提交时失败,则整个插入过程将回滚。

标签: c# asp.net entity-framework asp.net-core


【解决方案1】:

除了评论中建议的答案外,如果您希望执行单个查询以进行条目,您可以过滤已经存在的记录并尝试添加新的记录,如下所示。

try
   {
      var userAttsInDb =  await _context.UserAtt.Where(u => mhUserAtts.Any(x => x.Id == 
         u.Id)).Select(u => u.Id).ToArrayAsync();
      var mhUserAttsToAdd= mhUserAtts.Where(u => !userAttsInDb.Contains(u.Id));

      await _context.AddRangeAsync(mhUserAttsToAdd);
      await _context.SaveChangesAsync();
   }
catch(){ }

注意:您可能需要正确处理异步等待。

【讨论】:

  • 谢谢,这是一个很好的方法,我想知道当_context无法将它们保存在db中时,是否为每个返回的对象状态分配了错误。就像在早期的 ADO.net 中一样
  • 如果从多个线程或进程访问数据库,则数据可能在两个数据库查询之间发生了更改。这可能会导致错误。
【解决方案2】:

使用事务(如果你的数据库支持的话)

public async Task MyDataProcessingAsync(CancellationToken token) {
        using var context = new DbContext();
        using var transaction = await context.Database.BeginTransactionAsync(token);
        try {
            // adding, removing, updating...
            await context.SaveChangesAsync(token);
            await transaction.CommitAsync(token);
        }
        catch {
            // undo all changes
            await transaction.RollbackAsync();
            throw;
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    相关资源
    最近更新 更多