2011-05-11 52 views
11

例如,我的大部分實體都有DateCreated和DateModified字段。 SQL Server中的默認設置爲GetUtcDate()。有沒有簡單的方法讓EntityFramework使用SQL的默認值?

如果我嘗試創建一個實體並且不設置這些值,我會收到一個異常,說它不能運行SQL插入,因爲日期值超出範圍。有意義,因爲C#的默認日期是1/1/0001,而SQL Server的最小日期是1/1/1753。

那麼有沒有一種方法可以告訴EF要麼使用SQL Server默認值,要麼不嘗試插入尚未設置的列?

回答

12

您必須將這些屬性的StoreGeneratedPattern設置爲Identity對於DateCreatedComputed對於DataModified。它在設計師中可用。一旦你這樣做,你不能修改你的應用程序中的這些值 - 只有數據庫可以設置這些屬性。我寫了關於這個some article,因爲這個功能在VS2010 SP1之前有問題,但有報道說有時候它仍然不起作用。

+0

謝謝,我發佈之前嘗試過,但它不起作用。我正在使用VS 2010 Ultimate,SP1和EF4 – Rachel 2011-05-11 14:26:45

+0

在這種情況下,請檢查在EDMX文件的CSDL和SSDL部分都設置了正確的商店生成模式(必須將其打開爲XML),因爲這是有效的方式。 – 2011-05-11 14:31:13

+0

@Ladislav我正在給這個另一個嘗試,但是我得到關於一個不可空字段映射到可空實體屬性的錯誤。你知道它在說什麼嗎? – Rachel 2011-05-11 14:59:24

0

您是否嘗試過在實體中設置屬性的DefaultValue?

+0

我真的希望避免必須通過我所有的實體並調整每個屬性的默認值。此外,這意味着如果我更改SQL服務器的默認值,我需要更改EF中的默認值,並重新編譯 – Rachel 2011-05-11 14:06:01

4

一種解決方案是使用部分覆蓋您生成的entitycontext類。這將攔截所有的實體類的插入/更新您的EF方面:

public partial class MyEntities : ObjectContext 
{ 
    public override int SaveChanges(SaveOptions options) 
    { 
     this.DetectChanges(); 

     foreach (var insert in this.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added)) 
     { 
      if (insert.Entity.HasProperty("DateCreated")) 
       insert.Entity.GetType().GetProperty("DateCreated").SetValue(insert.Entity, DateTime.UtcNow, null); 
      if (insert.Entity.HasProperty("LastModified")) 
       insert.Entity.GetType().GetProperty("LastModified").SetValue(insert.Entity, DateTime.UtcNow, null); 
     } 

     foreach (var update in this.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Modified)) 
     { 
      if (update.Entity.HasProperty("LastModified")) 
       update.Entity.GetType().GetProperty("LastModified").SetValue(update.Entity, DateTime.UtcNow, null); 
     } 

     return base.SaveChanges(options); 
    } 
} 

或者做類似的事情,找你的時間戳字段插入/更新,並從ObjectStateEntries集合中移除呢?

相關問題