最近在做測試自己寫的分布式ORM時,發現進行資料集到實體集合轉換時,600條不到居然轉換了十多秒,其實做這種轉換做過多次,從來沒有出現這種情況,於是進行調試後發現,影響速度的主要是轉換時發生異常非常頻繁,系統在不斷的進行異常處理(因為轉換中可能出錯,但不會影響結果,我屏蔽了異常).再對比我原來寫的轉碼發現,由於很久沒寫這種代碼,這次寫的時候少了空值和類型轉換,直接寫了如下語句:
PropertyInfo.SetValue(obj, Value, null); //PropertyInfo未反射擷取的屬性資訊.
因為Value可能為空白,為空白就會報異常.系統因為要處理異常就會變得很慢,這也是500條記錄轉換成實體居然要十多秒的原因所在.看原來的代碼,並參照同事的建議改寫成如下:
if (PropertyInfo != null) { if (PropertyInfo.CanWrite) { if (Value != null && Value != DBNull.Value) { PropertyInfo.SetValue(obj, Convert.ChangeType(Value, PropertyInfo.PropertyType), null); } else { if (!PropertyInfo.PropertyType.IsValueType) { PropertyInfo.SetValue(obj, null, null); } } } }
上面代碼中,對於非實值型別(參考型別),賦空值在純粹的行記錄到實體物件的轉換時是沒有必要的,但這個函數也可以用於適用名稱賦值,所以我增加了該功能.經過修改後,600條記錄的轉換就正常了,速度還可以.其實原來做ORM時也寫過,對空值都做了處理,這次寫的時候無意識中進行了想當然的簡化,造成了轉換慢的問題.看來有些細節問題,很久沒關注就會忘掉.所以這次寫下來,爭取下次寫的時候別出錯,
PS:該賦值方法照樣不適用集合類型的賦值,但一般ORM時都不會有這個問題,所以沒有去做適應集合賦值的功能。