Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

find out the exact entity causing an exception in entity framework

The entity framework gives me generic messages in the exception without telling me the exact entity and the attribute which caused the error. How do I get more information about the error?

This happens in many cases such as

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

and

The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value. The statement has been terminated.

Exception details:

[SqlException (0x80131904): The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value. The statement has been terminated.] System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +404 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +412 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2660 System.Data.SqlClient.SqlDataReader.ConsumeMetaData() +59 System.Data.SqlClient.SqlDataReader.get_MetaData() +118 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +6431425 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +6432994 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +538 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +28 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +256 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +19 System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary2 identifierValues, List1 generatedValues) +270 System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) +391

[UpdateException: An error occurred while updating the entries. See the inner exception for details.] System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) +11223976 System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) +833 System.Data.Entity.Internal.InternalContext.SaveChanges() +218

[DbUpdateException: An error occurred while updating the entries. See the inner exception for details.] System.Data.Entity.Internal.InternalContext.SaveChanges() +291

like image 824
chadisbad Avatar asked May 02 '13 20:05

chadisbad


2 Answers

Here's the code I have in my solution:

try
{
    _context.SaveChanges();
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
    Exception raise = dbEx;
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
        foreach (var validationError in validationErrors.ValidationErrors)
        {
            string message = string.Format("{0}:{1}", validationErrors.Entry.Entity.ToString(), validationError.ErrorMessage);
            //raise a new exception inserting the current one as the InnerException
            raise = new InvalidOperationException(message , raise);
        }
    }
    throw raise;
}

You can use it as a basis to add into your solution ... it builds a nested set of exceptions with all the details from Entity Framework.

like image 191
qujck Avatar answered Oct 23 '22 01:10

qujck


You need to write tests for repositories and in the base class for your tests:

try
{
    DbContext.SaveChanges();
}
catch (DbEntityValidationException e)
{
    e.EntityValidationErrors.SelectMany(error => error.ValidationErrors).ToList().ForEach(
    item => Console.WriteLine("{0} - {1}", item.PropertyName, item.ErrorMessage));
    throw;
}
like image 22
Vlad Omelyanchuk Avatar answered Sep 28 '22 04:09

Vlad Omelyanchuk