【问题标题】:Log DbContext.SaveChanges Exception to the database in Entity Framework/Entity Framework Core将 DbContext.SaveChanges 异常记录到 Entity Framework/Entity Framework Core 中的数据库
【发布时间】:2018-09-23 11:52:11
【问题描述】:

在我的 asp.net 核心 Web 应用程序中,我正在将异常记录到数据库中。到目前为止一切正常,但问题是当 try 块中的 DbConext.SaveChanges 抛出异常时,无法将异常记录到数据库中catch block 中的 DbConext.SaveChanges 也会抛出相同的异常。

这是我迄今为止尝试过的代码:

try
{
    _unitOfWork.Repository<Product>().InsertEntity(product);
     await _unitOfWork.SaveChangesAsync();//This throws exception due the model validation failure
}
catch (Exception exception)
{
    ExceptionModel exceptionModel = new ExceptionModel();
    using (MyDbContext dbContext = new MyDbContext())
    {
        await dbContext.ExceptionModels.AddAsync(exceptionModel);
        await dbContext.SaveChangesAsync(); // Throws the same exception that was thrown in try block due to entity framework transaction
    }
}

注意:我猜这个问题是由实体框架事务引起的。

请帮助我如何克服这种情况将异常记录到数据库中。谢谢!

【问题讨论】:

  • 如果您告诉我们有关这些异常的详细信息...
  • 假设您未能将更改保存到数据库,因为数据库服务器已关闭。现在您想在数据库中记录一些内容以指示第一次保存失败。你预计会发生什么?
  • 抛出的exact异常是什么?
  • 使用一些外部服务,例如 Exceptionless,不要尝试/捕获。将数据库错误记录到同一个数据库中听起来是个坏主意。

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


【解决方案1】:

在 try 块中,您正在向 db 上下文添加一些更改。在保存时,您遇到了一些异常并在 catch 块中使用相同的数据库上下文来记录该异常。这里的 db 上下文仍然在 try 块中进行了未保存的更改。所以在保存上下文时你会得到同样的异常。

为避免这种情况,您必须在添加更多更改之前在 catch 块中丢弃来自 db 上下文的更改。

private void ResetContextState() => _context.ChangeTracker.Entries()
.Where(e => e.Entity != null && e.state == EntityState.Added).ToList()
.ForEach(e => e.State = EntityState.Detached);

编辑:上面的代码对我有用。

【讨论】:

    【解决方案2】:

    在 Entity framework Core 中,我使用 EF-Core Transaction 轻松解决了这个问题

    try
    {
        _unitOfWork.Repository<Product>().InsertEntity(product);
         await _unitOfWork.SaveChangesAsync();//This throws exception due the model validation failure
    }
    catch (Exception exception)
    {
        ExceptionModel exceptionModel = new ExceptionModel();
    
        string connectionString = _configuration.GetConnectionString("MyConnection");
    
        var options = new DbContextOptionsBuilder<MyDbContext>()
                    .UseSqlServer(new SqlConnection(connectionString))
                    .Options;
    
        using (var dbContext = new MyDbContext(options))
        {
             using (var transaction = dbContext.Database.BeginTransaction())
             {
                 try
                 {
                       dbContext.Exceptions.Add(exceptionModel);
                       await dbContext.SaveChangesAsync();
                       transaction.Commit();
                 }
                 catch (Exception e)
                 {
                     Console.WriteLine(e);
                     throw;
                 }
             }
         }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-19
      • 1970-01-01
      • 2020-05-28
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多