实体框架插入更新问题!

时间:2011-03-10 07:34:25

标签: 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-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] datetime
  • [DeletedOn] datetime

4 个答案:

答案 0 :(得分:7)

您未在添加的组实例中填充CreatedOnDeletedOn数据。 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();
}