6

I want to catch a foreign key exception when deleting an entity. But EF only throws custom exceptions. I need to check if there is a foreign key violation without checking all the relations "manually" via the EF.

try 
{
   applicationDbContext.SaveChanges();
   // even though debugger shows an SqlException at first, it doesnt get caught but an DBUpdateException is thrown...
   return RedirectToAction("Index");
}
catch (System.Data.SqlClient.SqlException ex)
{
   if (ex.Errors.Count > 0) 
   {
      switch (ex.Errors[0].Number)
      {
         case 547: // Foreign Key violation
                  ModelState.AddModelError("CodeInUse", "Country code could not be deleted, because it is in use");
                  return View(viewModel.First());
         default:
                  throw;      
       }
    }
}
Masoud
  • 8,020
  • 12
  • 62
  • 123
Hello It's me
  • 538
  • 1
  • 11
  • 24
  • Why don't you try to catch `DBUpdateException` instead? – DavidG Sep 19 '14 at 14:53
  • 1
    What exception does it throw? Look at the `InnerException`, it's probably what you're looking for. – Arian Motamedi Sep 19 '14 at 14:59
  • @DavidG When I catch `DbUpdateException` afterwards, it still doesnt catch the `SqlException`, which is thrown before the `DbUpdateException` – Hello It's me Sep 19 '14 at 15:41
  • Check my answer for ready to use utility methods for this: http://stackoverflow.com/questions/19042107/handle-exceptions-in-entity-framework-4/34670770#34670770 – yǝsʞǝla Jan 08 '16 at 06:28

2 Answers2

8

Catch DbUpdateException. Try this:

try 
{
    applicationDbContext.SaveChanges();
    return RedirectToAction("Index");
}
catch (DbUpdateException e) {
    var sqlException = e.GetBaseException() as SqlException;
    if (sqlException != null) {
        if (sqlException .Errors.Count > 0) {
            switch (sqlException .Errors[0].Number) {
                case 547: // Foreign Key violation
                    ModelState.AddModelError("CodeInUse", "Country code could not be deleted, because it is in use");
                    return View(viewModel.First());
                default: 
                    throw;      
            }
        }
    }
    else {
       throw;
    }                
}
jorgenv
  • 77
  • 1
  • 8
aquinas
  • 23,318
  • 5
  • 58
  • 81
  • It throws a *SqlException* or DbUpdateException? Did you check how many error there were? Did you check the error number of the first error? – aquinas Sep 19 '14 at 15:54
  • It throws two Exceptions, a SqlException `` and a DbUpdateException, which includes a InnerException from type SqlException. Both SqlExceptions have the error number 547. Actually it seems like the first SqlException is uncatchable because it not cause by `SaveChanges()` but by `System.Data.dll` – Hello It's me Sep 19 '14 at 16:32
0

I was able to catch unique key violation using System.Data.UpdateException exception type, didn't tried with foreign key violation. I think you can catch foreign key violation too.

Nilesh
  • 409
  • 3
  • 4