找出导致实体框架中的异常的确切实体

find out the exact entity causing an exception in entity framework

实体框架在异常中为我提供了一般消息,而没有告诉我导致错误的确切实体和属性。如何获取有关错误的更多信息?

这种情况在很多情况下都会发生,例如

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.

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

异常详细信息:

[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


以下是我在解决方案中的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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;
}

您可以将其作为基础添加到解决方案中…它使用实体框架中的所有细节构建一组嵌套的异常。


您需要为存储库和测试的基类编写测试:

1
2
3
4
5
6
7
8
9
10
try
{
    DbContext.SaveChanges();
}
catch (DbEntityValidationException e)
{
    e.EntityValidationErrors.SelectMany(error => error.ValidationErrors).ToList().ForEach(
    item => Console.WriteLine("{0} - {1}", item.PropertyName, item.ErrorMessage));
    throw;
}