Reflection應用於 LINQ 更新
- 2009-03-01
- 15962
- 0
demo在今天(現在是凌晨應該是說昨天)撰寫案子的時候遇到了一個問題,一個資料表中有超過30個欄位,因為現在demo都是用Linq在操作資料庫了,之前寫的時候也沒啥問題,但是這次的30個欄位難道我要和白癡一樣一行一行寫嗎?心中的OS:「程式不該是這樣」,想了一下呼叫了召喚獸,召喚獸給了一個關鍵字Reflection。
什麼是Reflection?Reflection字面上翻譯就是反映、反射的意思,在.Net內的Reflection很有趣,通常我們會知道一個物件的存在會順便知道它的型別屬性啥鬼的,但是有些時候我們只會知道有這個型別會在這裡用,不知道它會有什麼方法、欄位、屬性的時候就可以利用Reflection反推回去,是一個誇張方便的東西它的用處多多,demo也還沒完全掌握,所以更深入的介紹也不適合在這班門弄斧,這玩意是好物多多利用吧MSDN
好,回到主題以往我們使用Linq來做更新的時候你可能會這樣寫
var oldData=(from p in db.下拉清單 where p.ID==id select p).FirstOrDefault(); oldData.OO = ""; oldData.XX = ""; db.SubmitChanges();
很正常也很自然,但是當你遇到了10個欄位要更新呢?
var oldData=(from p in db.下拉清單 where p.ID==id select p).FirstOrDefault(); oldData.AA = ""; oldData.BB = ""; oldData.CC = ""; oldData.DD = ""; /*…………………*/ oldData.II = ""; db.SubmitChanges();
好,10個解決了那30個?50個?也都是這樣這寫嗎?,俗話說的好程式設計師就是要懶!!不懶就不會寫出更精簡的Code所以demo利用了Reflection的特性來去做了一件簡單的事情
//這是傳來要更新的物件 DemandSschedule.Models.OOXX newData //這裡是抓出資料庫原有物件 var dbData=(from p in db.OOXX where p.ID==id select p).FirstOrDefault(); /*以下這段code就動用到了 Reflection Linq部份預設你看得懂了,所以白話的翻譯就是 * 我利用newData的型別找到所有的屬性集合並且轉型為屬性敘述 * 過濾掉名稱為ID的 */ var t = from p in TypeDescriptor.GetProperties(newData).Cast<PropertyDescriptor>() where p.Name != "ID" select p; foreach (var item in t) { //這段忽然看可能會亂,多看幾次就懂了 item.SetValue(dbData, item.GetValue(newData)); } db.SubmitChanges();
這樣子你就可以看到威力了,不管我在OOXX裡面是有多少欄位都會更新了,完全不用去指定欄位,它就可以自己抓,那你可能又會說我要大量更新呢?很簡單阿Linq語法改一下不要去where ID再多跑一個迴圈就成了。
DemandSschedule.Models.OOXX newData var dbData=(from p in db.OOXX select p).ToArray(); var t = from p in TypeDescriptor.GetProperties(newData).Cast<PropertyDescriptor>() where p.Name != "ID" select p; foreach (var item in t) { for (int i = 0; i < dbData.Length; i++) { item.SetValue(dbData[i], item.GetValue(newData)); } } db.SubmitChanges();
這樣子的Code看起來就是爽!!
這一個小小的例子我們就可以發現Reflection的好用了,有很多之前不知道怎麼搞的部份都有解了,所以這項技能記得要點阿。
回應討論