Ответ 1
catch (DbEntityValidationException ex)
{
foreach (var item in ex.EntityValidationErrors)
{
//... inspect here
}
}
Вы можете найти необходимую информацию внутри цикла foreach.
Надеюсь, что это поможет.
Я прочитал много сообщений, связанных с этой проблемой, но не смог найти ответ. Я пытаюсь загрузить большой объем данных из Excel в SQL Server. Тысячи записей. И я получаю это исключение:
Строковые или двоичные данные будут усечены. Заявление было прекращается.
Очевидно, что некоторые значения превышают размер поля в базе данных. Ошибка возникает из SQL Server AFIK.
Мой вопрос. Как я мог узнать, какая запись и какое значение поля вызвали это?
В исключении EF нет особых сведений, кроме тех, которые я упоминал.
Любая помощь приветствуется.
Некоторые попросили фрагмент кода, но на самом деле это очень просто, проблема не в коде:
// employees is a List<Employee> collection loaded from Excel
using (var context = new Entities())
{
employees.ForEach(e => context.Employee.AddObject(e));
context.SaveChanges();
}
Также предложенный подход к использованию DbEntityValidationException (который доступен только в Entity Framework 5.0) не работает, блок catch не поймал исключение. p >
try
{
ImportData();
}
catch (DbEntityValidationException ex)
{
foreach (var item in ex.EntityValidationErrors)
{
//...
}
}
Единственное решение, которое я нашел, - это использовать SQL Server Profiler и определить следующие события для мониторинга:
Теперь я вижу, что электронная почта слишком длинная.
catch (DbEntityValidationException ex)
{
foreach (var item in ex.EntityValidationErrors)
{
//... inspect here
}
}
Вы можете найти необходимую информацию внутри цикла foreach.
Надеюсь, что это поможет.
Вы не можете на этом уровне. SQL Server отклоняет весь запрос.
Я бы добавил некоторые предварительные проверки данных против ваших ограничений базы данных для размера строки, формата даты и т.д.
В качестве альтернативы вы можете TRIM
поместить каждое строковое поле в необработанные данные в соответствующий размер поля, прежде чем пытаться вставить.
Вы можете проверить данные перед сохранением, используя метаданные EF и поднять соответствующую ошибку. Пожалуйста, проверьте следующий подход: http://www.entityframework.info/Home/MetadataValidation
Не уверен насчет усечения, но вот подсказка, когда вы получаете исключение, которое говорит вам изучить EntityValidationErrors. Usuaully при отладке не позволит вам увидеть это свойство (если у вас уже не было явного улова). Однако вы можете открыть быстрый просмотр и набрать $exception
. Теперь вы должны быть в состоянии развернуть и найти это свойство. Вы также можете просто ввести следующее:
(System.Data.Entity.Validation.DbEntityValidationException)$exception
private static string FindLongStrings(object testObject)
{
foreach (PropertyInfo propInfo in testObject.GetType().GetProperties())
{
foreach (ColumnAttribute attribute in propInfo.GetCustomAttributes(typeof(ColumnAttribute), true))
{
if (attribute.DbType.ToLower().Contains("varchar"))
{
string dbType = attribute.DbType.ToLower();
int numberStartIndex = dbType.IndexOf("varchar(") + 8;
int numberEndIndex = dbType.IndexOf(")", numberStartIndex);
string lengthString = dbType.Substring(numberStartIndex, (numberEndIndex - numberStartIndex));
int maxLength = 0;
int.TryParse(lengthString, out maxLength);
string currentValue = (string)propInfo.GetValue(testObject, null);
if (!string.IsNullOrEmpty(currentValue) && currentValue.Length > maxLength && lengthString!="max")
return testObject.GetType().Name + "." + propInfo.Name + " " + currentValue + " Max: " + maxLength;
}
}
}
return "";
}
foreach (object insert in dtx.GetChangeSet().Inserts)
{
string result = FindLongStrings(insert);
if (string.IsNullOrEmpty(result) == false)
{
responseBuilder.Append(result);
}
}
Если responseBuilder не пуст, он содержит имя поля, допустимую длину и сообщение об ошибке.