简体   繁体   中英

Log DbContext.SaveChanges Exception to the database in Entity Framework/Entity Framework Core

In my asp.net core web application, I am logging the exceptions to the database.Till now everything works fine but problem is that when the DbConext.SaveChanges in try block throws an exception, cannot log the exception to the database as DbConext.SaveChanges in catch block also throws the same exception.

Here is the code I have tried so far :

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

Note: I guess the problem is causing due to the Entity Framework transaction.

Please help how can I overcome this situation to log the exception to the database. Thanks!

In Entity framework Core, I have solved the problem easily using 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;
             }
         }
     }
}

In try block you are adding some changes to db context. While saving you got some exception and using the same db context in catch block to log that exception. Here the db context still has unsaved changes made in try block. So you will get the same exception while saving the context.

To avoid this you have to discard the changes from db context in catch block before adding more changes.

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

Edit: the above code worked for me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM