利用 POCO 解決 Entity Framework 的預設值 (Default Value) 寫入問題
經過 6 小時的實作和驗證後,原本文章 po 出來的作法,只有在小弟特定的專案和 UT 才可以執行 ( 原因尚不明 )
小弟重新建置相同的程式碼和資料庫後卻無法重現同樣的效果。
另外,雖然 很多文章在反應是 CSDL 有更新,但 SSDL 沒有更新是 Bug 。
但小弟導入 StoreGeneratedPattern = Computed 後,發現若是 SSDL 也改成 Computed 的話!
EF 就會忽略該欄位寫入的值,所以 之後要 update 其值就也不行。
這對某些欄位是沒辦法接受的,因此 SSDL 沒有改的話!還比較沒問題。
至少可以在 DTO 物件中加上初始化值 或是 Insert 語法時避開 來解決。
若是手動改 SSDL 的話,只要重新拉 Model 或是 更新,則 SSDL 就會被更新成 None 。
ps.. 目前確定 Identity 和 TimeStamp 這兩個欄位型態會將 SSDL 的設成 Computed
所以,目前 EF 的 預設值 有2種做法
- AP 都不會讀取 和 寫入,就不要加入到 EF 的 Model 上,就可以解決 insert 問題 ( 就是不要出現在 CSDL 中)
- AP 會讀寫,請直接在 POCO 上直接加上 預設值。 ( 可以的話用 Nullable<T> 或是 型別? )
直到 L 問起時才發現原來有這樣子的問題
( 感謝 R 協助 )
問題是若資料庫有「預設值」的情況時, EF 就沒有辦法寫入
當時 L 找到的解法只就以下兩種,不管是那一種都很不方便
一、改寫 SSDL ( EDMX 檔 ) ( 這個只要做一次資料庫同步後,剛剛改的就會不見了 )
二、該欄位每次都填值進去 ( 程式塞值進去就不叫做 預設值了 )
這個問題在各討論版都有出現過了workaround 的方式
其實,有另外的做法可以解決這個問題!!!
一開始小弟都沒有注意到大概是因為,小弟在第一時間就已經改寫成 POCO 型式的關係
之前有 po 過 EF 4 改寫 POCO 和 自動產生 POCO 物件 的文章,有興趣的可以參考
---------- 請特別注意! ----------------
v2
自訂工具「一定」要是空的喔!不然 Entity Framework 不會和 POCO 整合
不然等會更新 EDMX 的時候還是沒效果!!
-------------------------------------------------
為了證明是真的 ( 有圖有真相 )
所以我們就從建置 DB 開始吧!!
當然改 DB 要從 DB Project 開始,所有的修改都要納入版本管控,通常預設值都是不可為 null 的。
而且為了驗證多種不同的預設值,這裡特地加上了 TimeStamp 和 DateTime
因為,TimeStamp 型別本身已經會產生值了,所以在這裡只要補上 CreateDate 的就好!
都改好後就同步一份到 測試資料庫吧!!
Tip:若是您想要讓資料可以依 新增、修改 都會有最新的時間記錄的話。建議直接使用 TimeStamp就可以了,不需要另外再用程式去維護其最新的值。可以省下非常非常多的工
確認一下 CreateDate 的屬性,的確 StoreGeneratedPattern 是 Computed ! ( 先聲明,我沒有去改 SSDL )
那~~ 另外一個欄位 TimeStamp 去那了? 因為 TimeStamp 我的程式都不會去動到,所以剛剛我先刪除了。
---------------------------------------------------
v3
現在我重新建置卻一直都是 None 可能是因為當時不小心點到了吧!很囧
不過,重新再進行驗證後,其實發現 StoreGeneratedPattern 有沒有設定都沒關係!
( 之前都有先入為主的觀念 Orz )
目前知道會自動產生StoreGeneratedPattern 只有 Identity 和 TimeStamp 兩種格式
v2
若是原來就已經有這個欄位的話!那麼 StoreGeneratedPattern 就會用原來舊的
請重新建立 或是 手動改成正確的就行了!
---------------------------------------------------
因為模型上已經有了,所以 DTO 物件也要加上該對應欄位。不然會無法正常執行
( 到目前為止只要加上這一行 code 就好,其他的都先不用動。 )
改好後就要驗證,剛剛新增的欄位是否會對「即有」程式造成影響
當然用單元測試來跑,馬上就可以確認了。 ( 快速又簡單 )
因為是預設值驗證,所以就直接拿原本的 UnitTest 連改都不需要
可以看到測試中只有用到 .Name 的屬性 (欄位)
因為這段程式會自動產生三個預設值,所以也一併確認資料庫的內容,都可以看到 TimeStamp 和 CreateDate 都有預設值。
v3:為了有圖有真像,還是稍微把過程中斷將圖抓出來。
所以證明當 Entity Framework 4 + POCO 的組合時,預設值的問題是完全不會受到影響的。
而且再也不需要擔心同步資料庫後,修改 SSDL 後會被改回去。