最近在寫個小程式,赫然發現我所用的三個ORM對於DB欄位有預設值的支援度相當不佳,例如我在一個Table裡,設了一個叫guid的欄位為Primary Key,預設值為NEWID(),一般使用的習慣上,在Insert時是不需要對guid指定值的,但是使用Orm的時候,若不做特別設定的話,在Insert資料進去時,程式會塞進一段全為0的Guid,於是就會造成問題了。
下面分別介紹在Linq to SQL,Entity Framework,SubSonic 3.0上如何解決這個問題。
(據說用ADO.NET Entity Framework 4.0+配合ADO.NET C# POCO Entity Generator可以解決這個需手動修改的問題,不過這兩個東西我雖然灌是灌了,卻還沒有測試過,有機會測試再來說結果)
打開用SubSonic的T4 Templates產生的ActiveRecord.cs檔,找到那個table的位置,然後將
如此一來,在Insert的時候就不會發生錯誤了,不過比較起來,SubSonic 3.0是強制寫入一個Guid,而沒辦法設定成讓DB產生預設值,跟Linq to SQL與Entity Framework又有所不同,這點看來也只能這樣硬幹了,因為SubSonic官方覺得這不算是個問題,所以應該是不會去改善了。
下面分別介紹在Linq to SQL,Entity Framework,SubSonic 3.0上如何解決這個問題。
Linq to SQL
在Linq to SQL的data model檔裡( .dbml )將該欄位的 [Auto Generated Value] 設為 [True]Entity Framework
將Entity Framework的data model檔( .edmx )用文字編輯器打開,然後在SSDL的段落內找到那個table的位置,然後將該欄位的屬性加入StoreGeneratedPattern="Identity"。(據說用ADO.NET Entity Framework 4.0+配合ADO.NET C# POCO Entity Generator可以解決這個需手動修改的問題,不過這兩個東西我雖然灌是灌了,卻還沒有測試過,有機會測試再來說結果)
SubSonic 3.0
在SubSonic 3.0 可能有點複雜,因為它有ActiveRecord、SimpleRepository、Linq Templates三種方式可以用,我是用ActiveRecord,其他兩種沒試過,所以我只能說ActiveRecord的方式。打開用SubSonic的T4 Templates產生的ActiveRecord.cs檔,找到那個table的位置,然後將
partial void OnCreated();稍作修改,像我因為是在DB中預設值設為NEWID(),所以我改成這樣
void OnCreated() { if (this.guid==Guid.Empty) { this.guid = Guid.NewGuid(); } }
如此一來,在Insert的時候就不會發生錯誤了,不過比較起來,SubSonic 3.0是強制寫入一個Guid,而沒辦法設定成讓DB產生預設值,跟Linq to SQL與Entity Framework又有所不同,這點看來也只能這樣硬幹了,因為SubSonic官方覺得這不算是個問題,所以應該是不會去改善了。
No comments:
Post a Comment