demoshop

demo, trying to be the best_

Reflection應用於 LINQ 更新

  • 2013-01-08 11:42:31
  • 6857

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的好用了,有很多之前不知道怎麼搞的部份都有解了,所以這項技能記得要點阿。

http://msdn.microsoft.com/en-us/library/cxz4wk15.aspx

http://msdn.microsoft.com/zh-tw/library/cxz4wk15.aspx

回應討論