2011-03-10 163 views
0

我有一個實體框架的問題。特別是我不能做插入或更新操作。 錯誤消息:實體框架插入更新問題!

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]日期時間
+0

您可以發佈失敗的示例代碼嗎?此外,這應該給你一個提示:**將datetime2數據類型轉換爲日期時間數據類型導致超出範圍的值。** – BrokenGlass 2011-03-10 07:38:27

+0

可能,您正在給出DateTime。MinValue()到某處,它不在實體結構的範圍內。 – 2011-03-10 08:37:44

回答

7

你沒有填寫你的額外組實例CreatedOnDeletedOn DATAS。 EF可能發送默認的.NET值爲1/1/0001。它導致異常,因爲DATETIME列的SQL min允許值爲1/1/1753。請填寫代碼中的值或在數據庫中使用DATETIME2

+0

最小值爲1/1/1753,至少在MS SQL Server中。 – 2012-05-02 13:46:26

+0

@DanielLiuzzi:感謝您的糾正。你說得對,我會更新我的答案。 – 2012-05-02 15:30:57

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(); 
} 
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"); 
}