2017-08-30 12 views
4

背景: 我有200多個傳統的VB6應用程序,我將它們轉換爲C#,使用EntityFramework Core作爲我們的ORM。不幸的是,很多應用程序都使用MySQL的零日期(0000-00-00)。所以我需要迎合這一點,並能夠以某種方式存儲零日期。改變在200多款應用程序中運行的基本方式目前不是一種選擇。使用EF核心處理MySQL零日期

設置: 我可以定義表示在MySQL 例如字段定義的實體屬性:

public DateTime ExpiryDate { get; set; } 

... 

entity.Property(e => e.ExpiryDate) 
         .IsRequired() 
         .HasColumnType("datetime") 
         .HasDefaultValueSql("'0000-00-00 00:00:00'"); 

這將正確地存儲,如果沒有值上插入發送的零日期。

問題: 因爲C#有0001-01-01最小的日期是不可能讓我明確地存儲零日期。所以我的問題是......有沒有辦法設置我的實體來獲取這個零日期進出數據庫?

到目前爲止: 我一直在使用支持字段試過,定義爲一個字符串,這樣我可以操作任何DateTime.MinValue成爲'0000-00-00'。這使我能夠存儲零日期,但隨後導致鑄件的問題(如你所期望的)嘗試檢索數據時:

System.InvalidCastException:無法投 類型的對象「System.DateTime的」以鍵入'System.String'。我使用

當前套餐:

  • EFCore 1.1
  • PomeloEntityFrameWorkCore 1.1.2
  • 的MySQL 5.7.18
+0

問題:爲什麼當你想要一個零日期時該字段是必需的(並且可以爲空?)? – Stefan

+0

對不起,我使用可空的日期時間與我的支持現場測試結合使用。現在編輯。 – Bandito

+0

但問題仍然存在:該字段是必需的,但是默認使用默認的空日期。重點是;你是否使用這個空日期來確保所有新條目默認過期?或者,它只是將字段標記爲「未填充」的默認值。如果是後者,你可以允許「NULL」(即不要求),並進行相同類型的檢查來檢查字段的有效性。 – Stefan

回答

0

人們可能會認爲這是更適合作爲評論,但基本上,這是很長的。

和:

你得幫我了一點,因爲我沒有在手的工作系統,所以我從我的頭頂這樣做。 (和我在一個有點急的)

首先,開始時有沒有對應的屬性:

[NotMapped] 
public DateTime ExpiryDate { get; set; } 

這個屬性不被映射。這可能會導致有關數據庫的某些錯誤與模型不匹配,但我們可以克服這一點。查詢數據時,此屬性不會自動填充。所以,我們需要一種方法來處理這個我們自己。

例如,(這是一個壞榜樣,因爲我們需要在實體範圍內的某處):

[NotMapped] 
public DateTime? ExpiryDate 
{ 
    get 
    { 
     //of course you'll need some caching here 
     var s = context.Database.SqlQuery<string>("query to select datetime as string"); 
     //additional logic to determine validity: 
     if (s == "0000-00-00") 
      return null; 
     //else: 
     //do the conversion 
    } 
} 

這裏的基本問題;你想在EF框架內支持多遠?你只需要閱讀它,或者使用EF的變化跟蹤器等寫入。

還有其他的可能性,例如,執行一個執行CAST到SQL本身的nvarchar來獲取數據並進一步處理它。

也許ModelBuilder公開一些其他選項。

+0

感謝您的所有建議。因爲我需要使用EF和更改跟蹤器來檢索和存儲這些日期,所以我已經得出結論,在插入/更新/添加時使用數據庫觸發器將C#MinDate轉換爲MySQL零日期將會更清潔。看來EF Core將來會允許自定義類型映射,這應該可以解決這個問題:https://github.com/aspnet/EntityFrameworkCore/issues/242 – Bandito