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

Posted

技术标签:

【中文标题】在实体框架中找出导致异常的确切实体【英文标题】:find out the exact entity causing an exception in entity framework 【发布时间】:2013-05-02 20:35:28 【问题描述】:

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

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

操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

将 datetime2 数据类型转换为 datetime 数据类型导致值超出范围。声明已终止。

异常详情:

[SqlException (0x80131904):将 datetime2 数据类型转换为 datetime 数据类型导致值超出范围。 该语句已终止。] System.Data.SqlClient.SqlConnection.OnError(SqlException 异常, 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,布尔返回流,布尔异步)+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 方法) +28 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior 行为,字符串方法)+256 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior 行为)+19 System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator 翻译器,EntityConnection 连接,Dictionary2 identifierValues, List1 generatedValues)+270 System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter 适配器) +391

[UpdateException:更新条目时出错。有关详细信息,请参阅内部异常。] System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter 适配器) +11223976 System.Data.Objects.ObjectContext.SaveChanges(SaveOptions 选项)+833 System.Data.Entity.Internal.InternalContext.SaveChanges() +218

[DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。] System.Data.Entity.Internal.InternalContext.SaveChanges() +291

【问题讨论】:

您在多少个地方使用Datetime2?阅读this。 【参考方案1】:

这是我的解决方案中的代码:

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;

您可以将其作为基础添加到您的解决方案中...它构建了一组嵌套的异常,其中包含来自 Entity Framework 的所有详细信息。

【讨论】:

我认为这对第一个错误有好处,但对于第二个错误我没有得到DbEntityValidationException 我得到这个:[DbUpdateException: An error occurred while updating the entries. See the inner exception for details.] @chadisbad 内部异常说什么? 内部异常是The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value. The statement has been terminated.我想知道是否可以找出导致异常的具体实体和属性(列)。 这个catch封装了cuncurrency异常? @SantiagoBenitez 抱歉,但我不知道他们是如何处理的。它可能会,也可能不会,这取决于 EF 如何呈现它们。【参考方案2】:

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

try

    DbContext.SaveChanges();

catch (DbEntityValidationException e)

    e.EntityValidationErrors.SelectMany(error => error.ValidationErrors).ToList().ForEach(
    item => Console.WriteLine("0 - 1", item.PropertyName, item.ErrorMessage));
    throw;

【讨论】:

上述解决方案不适用于 mysql 数据库。由于 MySql 连接器抛出 MySql.Data.MySqlClient.MySqlException 类型的异常。任何想法在这种情况下可以做什么?

以上是关于在实体框架中找出导致异常的确切实体的主要内容,如果未能解决你的问题,请参考以下文章

带有 MySQL 连接器 6.4.3 的实体框架 4 自动生成表导致“列长度”异常

如何删除实体框架中的循环引用?

扩展MVC5和实体框架6 ApplicationUser导致用户注册无效列错误

实体框架 - MySQL - 未知异常

有时实体框架在将“子”添加到新(父)元素后插入多个“父”行

EF生成实体模型注意事项