2013-05-02 65 views
6

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

这发生在许多情况下,如

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

一个DATETIME2数据类型为datetime数据类型的转换导致外的范围内的值。该语句已终止。

异常详细信息:

[SQLEXCEPTION(0x80131904):一个DATETIME2数据类型为datetime数据类型的转换导致外的范围内的值。 该语句已终止。] System.Data.SqlClient.SqlConnection.OnError(SqlException异常,布尔breakConnection)404 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()412 System.Data.SqlClient.TdsParser。运行(runBehavior runBehavior,SqlCommand的cmdHandler,SqlDataReader的数据流,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj)2660 System.Data.SqlClient.SqlDataReader.ConsumeMetaData()+59 System.Data.SqlClient.SqlDataReader.get_MetaData()+118 系统。 Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,RunBehavior runBehavior,String resetOptionsString)+6431425 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior ,布尔returnStream,布尔异步)+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,布尔returnStream,String方法)+28 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior行为,String方法)+256 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior行为)+19 系统。 Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator转换器,EntityConnection连接,字典2 identifierValues, List 1 generatedValues)+270 System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManag er stateManager,IEntityAdapter适配器)+391

[UpdateException:更新条目时发生错误。有关详细信息,请参阅内部异常。] System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager,IEntityAdapter adapter)+11223976 System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)+833 系统。 Data.Entity.Internal.InternalContext.SaveChanges()+218

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

+0

多少地方,你使用'Datetime2'?阅读[this](http://stackoverflow.com/a/1334193/1466627)。 – 2013-05-03 13:40:10

回答

7

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

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

你可以使用它作为基础,添加到您的解决方案......它建立一个嵌套包含实体框架中所有细节的一组异常。

+0

我认为这对于第一个错误是好的,但对于第二个错误我没有得到'DbEntityValidationException'我得到这个:'[DbUpdateException:更新条目时发生错误。细节见内部例外。] – chadisbad 2013-05-03 03:21:11

+0

@chadisbad内部例外说什么? – qujck 2013-05-03 08:09:23

+0

内部异常是'将datetime2数据类型转换为日期时间数据类型导致超出范围的值。该声明已被终止。“我想知道是否可以找出导致异常的特定实体和属性(列)。 – chadisbad 2013-05-03 12:52:15

1

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

try 
{ 
    DbContext.SaveChanges(); 
} 
catch (DbEntityValidationException e) 
{ 
    e.EntityValidationErrors.SelectMany(error => error.ValidationErrors).ToList().ForEach(
    item => Console.WriteLine("{0} - {1}", item.PropertyName, item.ErrorMessage)); 
    throw; 
} 
+0

以上解决方案对于MySql数据库不起作用。由于MySql连接器抛出类型为MySql.Data.MySqlClient.MySqlException的异常。任何想法在这种情况下可以做什么? – 2017-11-16 08:18:18