目錄: 前言 設計(完成擴展) 實現效果 擴展設計方案 擴展後代碼結構 集思廣益(問題) 前言: 在上一篇文章我寫瞭如何重建IDbCommandTreeInterceptor來實現創建人、創建時間、更新人、更新時間的統一賦值。看起來會比較複雜,有人提到了重寫SaveChanges來實現,這個是很好的 ...
目錄:
設計(完成擴展)
前言:
在上一篇文章我寫瞭如何重建IDbCommandTreeInterceptor來實現創建人、創建時間、更新人、更新時間的統一賦值。看起來會比較複雜,有人提到了重寫SaveChanges來實現,這個是很好的建議,確實會更簡單些。可我依舊要堅持在IDbCommandTreeInterceptor實現,具體原因嗎?
有一些系統要求對實體插入更新時,保存的創建時間、更新時間為資料庫伺服器時間(getdate()),關於讓時間保存為資料庫伺服器時間一般有2種做法:
1、從資料庫伺服器讀取返回時間對實體進行賦值。
2、在資料庫創建時間上設置預設值,而更新時間則需要建立觸發器。
為什麼需要存為資料庫伺服器時間:程式執行環境系統的時間可能和資料庫伺服器有差異,而這種差異在很多系統可能是致命的。一些桌面端應用(運行在用戶電腦),沒有設計服務層、客戶端直接調用EF組件訪問資料庫,很不湊巧,有人就遇到這種系統。
大概就是這樣,如果要用我之前代碼實現這個功能有兩種可能性:
1、修改擴展EntityFramework.SqlServer部分代碼
2、使IDbCommandTreeInterceptor、IDbCommandInterceptor兩者在執行過程中建立關係,篡改DbCommand的CommandText、Parameters。
其實兩種實現方式我都不推薦,我還是使用第二種方式完成了這個實現,不過實際項目不推薦這麼使用。
設計:
設計實現效果:
還是使用原有的配置
擴展設計方案:
我在昨天的思維導圖裡提示了IGetDbExpression介面為什麼要耦合到DbExpression,其實就是為了在不修改SimpleSSOCommandTreeInterceptor情況下完成這個另類功能的實現,讓SimpleSSOCommandTreeInterceptor承當更少的職責。
代碼結構(類型之間的依賴關係):
右上角為新增的兩個類,如果擴展IntercepterGeneratedType則需要調整右上角兩個類及IGetDbExpression實現。
大概就是這樣,對於EF,我也有兩年沒怎麼用了。之前一直在追求許多技術上的最佳實踐,對於系統技術的複雜度可以說是恆定的,可是系統的複雜度隨著業務的擴展有時候是呈指數級增長的。這兩年去一些大型電商公司、製造企業瞭解學習他們的業務,技術相對落後,中途改造了許多龐大且設計異常糟糕的系統,問題基本都是線上的,情況就是你們IT部門大部分人每天幾十個人找,總的說來這兩年還是收穫頗豐的。
集思廣益:
之前公司有使用到網上找到的自建資料庫函數fun_split,這個函數執行結果沒有問題,不過更嚴重的就是,當@input參數字元達到一定長度,隨著長度增加,執行時間可以說呈指數級別的增長。
代碼:
create function fun_split(@input varchar(max),@pattern varchar(10)) returns @temp table(a varchar(100)) --實現split功能 的函數 --說明:@input,字元串,如a:b:c;@pattern,分隔標誌,如 : as begin declare @i int set @input=rtrim(ltrim(@input)) set @i=charindex(@pattern,@input) while @i>=1 begin insert @temp values(left(@input,@i-1)) set @input=substring(@input,@i+1,len(@input)-@i) set @i=charindex(@pattern,@input) end if @input<>'' insert @temp values(@input) return end
如何修改調整這段代碼完成優化,有興趣的朋友可以看下,有點意思。