Подтвердить что ты не робот

Исключение EF: Строковые или двоичные данные будут усечены. Заявление было прекращено.?

Я прочитал много сообщений, связанных с этой проблемой, но не смог найти ответ. Я пытаюсь загрузить большой объем данных из 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 и определить следующие события для мониторинга:

enter image description here

enter image description here

Теперь я вижу, что электронная почта слишком длинная.

4b9b3361

Ответ 1

catch (DbEntityValidationException ex)
{
    foreach (var item in ex.EntityValidationErrors)
    {
        //... inspect here 
    }
}

Вы можете найти необходимую информацию внутри цикла foreach.

Надеюсь, что это поможет.

Ответ 2

Вы не можете на этом уровне. SQL Server отклоняет весь запрос.

Я бы добавил некоторые предварительные проверки данных против ваших ограничений базы данных для размера строки, формата даты и т.д.

В качестве альтернативы вы можете TRIM поместить каждое строковое поле в необработанные данные в соответствующий размер поля, прежде чем пытаться вставить.

Ответ 3

Вы можете проверить данные перед сохранением, используя метаданные EF и поднять соответствующую ошибку. Пожалуйста, проверьте следующий подход: http://www.entityframework.info/Home/MetadataValidation

Ответ 4

Не уверен насчет усечения, но вот подсказка, когда вы получаете исключение, которое говорит вам изучить EntityValidationErrors. Usuaully при отладке не позволит вам увидеть это свойство (если у вас уже не было явного улова). Однако вы можете открыть быстрый просмотр и набрать $exception. Теперь вы должны быть в состоянии развернуть и найти это свойство. Вы также можете просто ввести следующее:

(System.Data.Entity.Validation.DbEntityValidationException)$exception

Ответ 5

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 не пуст, он содержит имя поля, допустимую длину и сообщение об ошибке.