DbUpdateException:导致"字符串或二进制数据被截断"的字段

Doo*_*ght 7 c# entity-framework exception entity-framework-6

我收到了一条DbUpdateException消息

字符串或二进制数据将被截断

据我所知,实体中的一个字段不符合数据库中列的长度.我可以下来手动检查它们.

然而,我想要做的是得到一个明智的错误信息,它可能告诉我它实际上是哪个字段!例如

字符串或二进制文件将在字段ProspectName处截断.

我能够打印出很多随机信息.并尝试了各种各样的东西.但没有任何东西指向字段名称.

请注意,这不是类型DbEntityValidationException,它是一个类型DbUpdateException

// DbUpdateException exception
foreach (var entry in exception.Entries)
{ 
    builder.AppendLine(String.Format("Error at: Type {0}", entry.Entity.GetType().Name));

    if ((exception.InnerException is System.Data.Entity.Core.UpdateException) &&
        (exception.InnerException.InnerException is System.Data.SqlClient.SqlException))
    {
        var updateException = (System.Data.Entity.Core.UpdateException)exception.InnerException;

        var sqlException = (System.Data.SqlClient.SqlException)exception.InnerException.InnerException;
        var result = new List<ValidationResult>();

        for (int i = 0; i < sqlException.Errors.Count; i++)
        {
            builder.AppendLine(String.Format("Error code: {0} ", sqlException.Errors[i].Number));
            builder.AppendLine(String.Format("Source: {0} ", sqlException.Errors[i].Source));
            builder.AppendLine(String.Format("Message: {0} ", sqlException.Errors[i].Message));
            builder.AppendLine(String.Format("State: {0} ", sqlException.Errors[i].State));
            builder.AppendLine(String.Format("Procedure: {0} ", sqlException.Errors[i].Procedure));
        } 
    }
}
Run Code Online (Sandbox Code Playgroud)

完成错误:

字符串或二进制数据将被截断.该语句已终止.

错误:键入tree_1ECACDBB4458C7A9DEC7CD183FD8B8C3473502FEFFACF160E17AD47718DCE5EA
错误代码:8152
源:.Net SqlClient数据提供程序
消息:字符串或二进制数据将被截断.
状态:14
过程:
错误代码:3621
源:.Net SqlClient数据提供程序
消息:语句已终止.
状态:0
程序:

Dry*_*ods 6

一个“丑陋”的解决方案(但是可以使用并且仅使用C#代码)可以准确地找到哪个属性会给您带来该错误,即:

如果您要进行更新,请执行以下操作:

 var myDBObj = db.Mytables.Where(x=>x.Id == myId).FirstOrDefaul();
 if(myDBObj == null) return false; // or something else with the error msg

 myDBObj.Property1 = myObjToSave.Property1;
 db.SaveChanges();

 myDBObj.Property2 = myObjToSave.Property2;
 db.SaveChanges();

 myDBObj.Property3 = myObjToSave.Property3;
 db.SaveChanges();
 .... // EACH PROPERTY....
 myDBObj.PropertyX = myObjToSave.PropertyX;
 db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

现在,有了制动点或用于跟踪“位置”的增量变量,等等。。。在这种特殊情况下,您将确切地知道有例外。

注意:这是一个丑陋的解决方案,仅用于跟踪出现故障的位置...切勿在生产中使用它...当然,IMO还有其他更友好的功能,例如拥有sql profiler并查看生成的SQL,然后尝试在sql Management Studio上运行它,然后在那看到错误……

更新#1

像这样的东西(注意:我没有编译):P

Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties();  
string lastPropertyWithError = ""; // You can replace this with a list or so  
foreach (PropertyInfo property in properties)
{
   try{
    property.SetValue(myDBObj, property.GetValue(myObj, null));
    db.SaveChanges();
   }catch()
   {
     lastPropertyWithError  = property.Name;
   }
}
Run Code Online (Sandbox Code Playgroud)