Исключение переполнения SqlDateTime в Entity Framework - PullRequest
0 голосов
/ 15 декабря 2009

При вызове context.SaveChange() я получаю исключение: {"An error occurred while updating the entries. See the InnerException for details."} с InnerException "SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM."

Как правило, эту ошибку довольно легко исправить - просто найдите свойство DateTime, значение которого никогда не устанавливалось (по умолчанию MinValue). К сожалению, я проверил все свойства моего объекта, и все они установлены на допустимые даты / время.

Есть ли способ выяснить, на какое свойство ссылается EF при создании этого исключения?

Кроме того, я на самом деле проверяю только объект, который я добавил в контекст, прямо перед SaveChanges (и, насколько я знаю, я только добавляю 1). Есть ли способ просмотреть все ожидающие данные, которые будут сохранены?

Редактировать

InnerException.StackTrace:

at System.Data.SqlTypes.SqlDateTime.FromTimeSpan(TimeSpan value)
at System.Data.SqlTypes.SqlDateTime.FromDateTime(DateTime value)
at System.Data.SqlClient.MetaType.FromDateTime(DateTime dateTime, Byte cb)
at System.Data.SqlClient.TdsParser.WriteValue(Object value, MetaType type, Byte scale, Int32 actualLength, Int32 encodingByteSize, Int32 offset, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary`2 identifierValues, List`1 generatedValues)
at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)

Редактировать 2

Возможно, что-то должно быть связано с моим рабочим процессом ... Например ...

  • Я строю объект SalaryInformation в классе, отвечающем за создание объектов Entity
  • SalaryInformation имеет свойство Employee, но класс, который его создает, знает только идентификатор Employee, поэтому он устанавливает SalaryInformation.Employee = new Employee {ID = 1} (оставляя поля даты в MinValue)
  • Я передаю объект SalaryInformation в метод для сохранения
  • Внутри метода save я ищу объект Employee в базе данных на основе идентификатора, а затем присваиваю возвращенный объект Employee SalaryInformation.Employee
  • Я тогда context.AddToSalaryInformation(SalaryInformation) и context.SaveChanges()

Я подозреваю, что это оставляет Сотрудника-отставшего в контексте только с установленным идентификатором и без Даты, таким образом, ошибка.

Редактировать 3

Действительно, рабочий процесс был проблемой. Если я просто скажу `SalaryInformation.Employee = null; ' перед назначением объекта сотрудника из базы данных, отставший уходит и ошибки не возникает.

Это предполагаемое поведение и обходной путь? Это кажется ужасным.

Ответы [ 2 ]

3 голосов
/ 16 декабря 2009

Вы неправильно настраиваете сотрудника. Самый простой способ сделать это:

SalaryInformation.Employee = context.Employees.Where(e => e.Id == 1).First();
context.AddToSalaryInformation(SalaryInformation);

Это означает доступ к БД.

В EF 4 с ассоциациями FK вы можете сделать:

SalaryInformation.EmployeeId = 1;
context.AddToSalaryInformation(SalaryInformation);

В EF 1 обходной путь:

SalaryInformation.EmployeeReference.EntityKey = 
    new EntityKey("MyEntities.Employees", "Id", 1);
context.AddToSalaryInformation(SalaryInformation);

Но создание заглушки, как вы делаете во втором примере, требует дополнительной работы .

1 голос
/ 15 декабря 2009

Используйте средство профилирования SQL и запустите трассировку.

[Изменить] Вы также можете попробовать реализовать трассировку EF, как описано здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...