我的实体框架有问题。特别是我不能做插入或更新操作。 错误讯息:
An error occurred while updating the entries. See the inner exception for details.System.Data.SqlClient.SqlException (0x80131904): The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.
The statement has been terminated.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
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)
你能帮助我吗?
示例代码:
ProductGroups group;
if (txtProductGroupName.Text.Trim() != null)
{
group = new ProductGroups();
group.ProductGroupName = txtProductGroupName.Text.Trim();
context.ProductGroups.AddObject(group);
context.SaveChanges();
context.AcceptAllChanges();
lblState.ForeColor = Color.Red;
lblState.Text = "Ürün grubu kaydedildi...";
}
else
{
lblState.ForeColor = Color.Red;
lblState.Text = "Ürün grubu ismini bos geçmeyiniz";
}
ProductGroups表定义为5列:
答案 0 :(得分:7)
您未在添加的组实例中填充CreatedOn
和DeletedOn
数据。 EF可能发送默认的.NET值为1/1/0001。它导致异常,因为SQL min允许DATETIME
列的值是1/1/1753。填写代码中的值或在数据库中使用DATETIME2
。
答案 1 :(得分:2)
请看这篇文章。它对您有用 - Using sql date data type and EF4。
答案 2 :(得分:2)
加入BenSwayne的回答:
如果您更新的实体不是来自数据库,则必须告知实体框架不更新CreatedOn属性。为此,请使用以下代码更新代码:
if (entry.State == EntityState.Added)
{
e.CreatedOn = currentTime;
}
else
{
// handle updates of objects not originating from the database
var objectStateManager = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager;
ObjectStateEntry entryToUpdate = objectStateManager.GetObjectStateEntry(entry.Entity);
entryToUpdate.RejectPropertyChanges("CreatedOn");
}
答案 3 :(得分:0)
虽然目前的答案解释了您遇到此错误的原因,但没有人提出解决方案或最佳做法。
这里最正确的答案是你应该让你的日期字段在模型中可以为空,或者在所有插入过程中提供一个值!
您无需使用DateTime2数据类型,这只是额外的开销,并不能解决问题。当然,您不希望服务器为这两个字段生成默认值。
我建议在插入期间设置CreatedOn,DeletedOn应该可以为空。
需要注意的一点是,实体框架DbContext提供了一个可以在上下文类中覆盖的SaveChanges()方法。您可以使用此方法拦截EF保存并插入审计字段等数据。我有一个模型基类,它包含我所有模型继承的所有常见审计数据,如CreatedOn。然后我可以更新我的上下文中的任何记录的审核日期(使用EF 4.3 DbContext):
public override int SaveChanges()
{
var currentTime = DateTime.UtcNow;
foreach (var entry in ChangeTracker.Entries<Models.Abstract.ModelBase>())
{
// If this is a new entity add to the Db set the CreatedOn field to now
if (entry.State == EntityState.Added)
{
entry.Entity.CreatedOn = currentTime;
}
// Always set the modified by/on
entry.Entity.ModifiedOn = currentTime;
}
return base.SaveChanges();
}