实体框架中的SqlDateTime溢出异常

时间:2009-12-15 17:12:34

标签: entity-framework ado.net

调用context.SaveChange()时,我收到一个异常:{"An error occurred while updating the entries. See the InnerException for details."},其内部异常为"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
  • SalaryInformation上有一个Employee属性,但构建它的类只知道Employee ID,因此它设置SalaryInformation.Employee = new Employee {ID = 1}(将日期字段设置为MinValue)
  • 我将SalaryInformation对象传递给要保存的方法
  • 在save方法中,我根据ID查找数据库中的Employee对象,然后将返回的Employee对象分配给SalaryInformation.Employee
  • 然后我context.AddToSalaryInformation(SalaryInformation)context.SaveChanges()

我怀疑这会在上下文中留下一个落后的员工,只有ID设置,没有日期,因此错误。

编辑3

确实,工作流程是个问题。如果我只是说'SalaryInformation.Employee = null;'在从数据库中分配employee对象之前,straggler会消失,并且不会发生错误。

这是预期的行为并且可以解决吗?这看起来很可怕。

2 个答案:

答案 0 :(得分:3)

您正在以错误的方式设置员工。最简单的方法是:

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

但是,就像你在第二个例子中那样创建一个存根,requires additional work

答案 1 :(得分:1)

使用SQL事件探查器工具并运行跟踪。

[编辑] 您还可以尝试按照here所述实现EF跟踪。