Linq 实体框架插入更新问题!

Linq 实体框架插入更新问题!,linq,entity-framework-4,entity,Linq,Entity Framework 4,Entity,我对实体框架有问题。特别是我不能做插入或更新操作。 错误消息: 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-r

我对实体框架有问题。特别是我不能做插入或更新操作。 错误消息:

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列定义:

  • [ProductGroupID]int
  • [ProductGroupName]varchar(100)
  • [ProductGroupComment]varchar(1000)
  • [CreatedOn]日期时间
  • [DeletedOn]日期时间

您没有在添加的组实例中填充
CreatedOn
DeletedOn
数据。EF可能发送了默认的.NET值,即1/1/0001。它导致异常,因为
DATETIME
列的SQL最小允许值为1/1/1753。要么在代码中填充值,要么在数据库中使用
DATETIME2

您没有在添加的组实例中填充
CreatedOn
deleteddon
数据。EF可能发送了默认的.NET值,即1/1/0001。它导致异常,因为
DATETIME
列的SQL最小允许值为1/1/1753。要么在代码中填入值,要么在数据库中使用
DATETIME2

请看这篇文章。它可能对你有用-。

请看这篇文章。它可能对您有用-。

虽然当前的答案解释了您遇到此错误的原因,但没有人提出解决方案或最佳做法

这里最正确的答案是,您应该使您的日期字段在模型中为空,或者在所有插入期间提供一个值

您不需要使用DateTime2数据类型,这只是额外的开销,并不能解决问题。您当然不希望服务器为这两个字段生成默认值

我建议在插入期间设置CreatedOn,DeletedOn应该可以为null


值得注意的是,entity framework DbContext提供了一个SaveChanges()方法,您可以在上下文类中重写该方法。您可以使用此方法截取EF保存并插入数据,如审核字段。我有一个模型基类,它包含我所有模型继承的所有常见审计数据,如CreatedOn。然后,我可以更新上下文中任何记录的审核日期,如下所示(使用EF 4.3 DbContext):

public override int SaveChanges()
{
var currentTime=DateTime.UtcNow;
foreach(ChangeTracker.Entries()中的var条目)
{
//如果这是一个新实体,则将CreatedOn字段设置为now
if(entry.State==EntityState.Added)
{
entry.Entity.CreatedOn=当前时间;
}
//始终将“修改人”设置为“开”
entry.Entity.ModifiedOn=当前时间;
}
返回base.SaveChanges();
}

虽然当前的答案解释了您遇到此错误的原因,但没有人提出解决方案或最佳做法

这里最正确的答案是,您应该使您的日期字段在模型中为空,或者在所有插入期间提供一个值

您不需要使用DateTime2数据类型,这只是额外的开销,并不能解决问题。您当然不希望服务器为这两个字段生成默认值

我建议在插入期间设置CreatedOn,DeletedOn应该可以为null


值得注意的是,entity framework DbContext提供了一个SaveChanges()方法,您可以在上下文类中重写该方法。您可以使用此方法截取EF保存并插入数据,如审核字段。我有一个模型基类,它包含我所有模型继承的所有常见审计数据,如CreatedOn。然后,我可以更新上下文中任何记录的审核日期,如下所示(使用EF 4.3 DbContext):

public override int SaveChanges()
{
var currentTime=DateTime.UtcNow;
foreach(ChangeTracker.Entries()中的var条目)
{
//如果这是一个新实体,则将CreatedOn字段设置为now
if(entry.State==EntityState.Added)
{
entry.Entity.CreatedOn=当前时间;
}
//始终将“修改人”设置为“开”
entry.Entity.ModifiedOn=当前时间;
}
返回base.SaveChanges();
}

在本斯韦恩的回答中添加:

如果更新的实体不是来自数据库,则必须告诉实体框架不要更新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");
}

本斯韦恩的回答补充道:

如果更新的实体不是来自数据库,则必须告诉实体框架不要更新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");
}

你能发布失败的示例代码吗?此外,这还应该给您一个提示:将datetime2数据类型转换为datetime数据类型会导致值超出范围。您可能正在向某个位置提供datetime.MinValue(),但它不在实体结构的范围内。是否可以发布失败的示例代码?此外,这应该给您一个提示:将datetime2数据类型转换为datetime数据类型会导致值超出范围。可能是您将datetime.MinValue()指定给了某个位置,但它不在实体结构的范围内。最小值为1/1/1753,至少在MS SQL Server中是如此。@DanielLiuzzi:谢谢您的更正。您是对的,我将更新我的答案。最小值是1/1/1753,至少在MS SQL Server中是这样。@DanielLiuzzi:谢谢您的更正。你是对的,我会更新我的答案。