什麼是Linq表達式?什麼是Lambda表達式? 如圖: 由此可見Linq表達式和Lamdba表達式並沒有什麼可比性。 那與Lamdba表達式相關的整條語句稱作什麼呢?在微軟並沒有給出官方的命名,在《深入理解C#》中稱為點標記。 ...
什麼是Linq表達式?什麼是Lambda表達式?
如圖:
由此可見Linq表達式和Lamdba表達式並沒有什麼可比性。
那與Lamdba表達式相關的整條語句稱作什麼呢?在微軟並沒有給出官方的命名,在《深入理解C#》中稱為點標記。
查詢表達式、點標記你更喜歡哪個?
所以,我們的標題的提問根本就不合適。應該是“Linq查詢表達式和點標記你更喜歡哪個?”。如:
//查詢表達式 var students1 = from t in db.Students where t.Name == "張三" select new { t.Id, t.Name, t.Age }; //點標記 var students2 = db.Students .Where(t => t.Name == "張三") .Select(t => new { t.Id, t.Name, t.Age });
為什麼選擇點標記
我相信更多的人偏向選擇點標記。具體什麼原因我也說不清(可能是點標記中的Lamdba更加優雅吧)。對於我個人來說,也是更加喜歡點標記這種方式。
1、所有的查詢表達式都可以轉成對應的點標記。反之,不是所有的點標記都可以轉成查詢表達式。
為什麼?因為查詢表達式在編譯後就直接變成了點標記:(以下是上面兩個語句對應的編譯後的反編譯C#代碼)
生成了一模一樣的代碼。(由於是編譯後的,好多亂七八糟的代碼。我們只看Where和Select關鍵字就知道,使用的都是點標記。)
2、點標記確實比查詢表達式更加優雅
例一:
//查詢表達式 var students1 = from t in db.Students where t.Name == "張三" select t; //點標記 var students2 = db.Students .Where(t => t.Name == "張三");
我為什麼一定要 select t 啊,這句沒卵用的廢話就不能省嗎?是的,省了就報錯:
例二:
必須需要括弧包裹起來才能取結果集?你還能更醜一點嗎?
//查詢表達式 var students1 = (from t in db.Students where t.Name == "張三" select t).ToList(); //點標記 var students2 = db.Students .Where(t => t.Name == "張三") .ToList();
例三:(為什麼說:"不是所有的點標記都可以轉成查詢表達式"【此例只適用於IEnumerator】)
此條點標記你能轉成查詢表達式嗎?
var list = new List<string>() { "張三", "張三", "張三", "張三", "李四", "張三", "李四", "張三", "李四" }; var students2 = list .Where((item, index) => item == "張三" && index % 2 == 0) .Select((item, index) => new { item, index }) .ToList();
查詢表達式你能Reverse嗎?
var list = new List<string>() { "張三1", "張三2", "張三3", "張三0", "李四9", "張三3", "李四", "張三2", "李四" }; var students2 = list .Where((item, index) => item.Contains("張三")) .Select((item, index) => new { item, index }) .Reverse()//反序 .ToList();
什麼時候使用查詢表達式?
通過上面的對比,好像查詢表達式一文不值了。no,不是這樣的。
比如下麵幾種情況我們就可以選擇使用查詢表達式:
例一:(本例適用於Linq to Object 和 沒有建主外鍵的EF查詢)
點標記中的Join需要傳四個參數表達式,是不是有點暈了。。。
var list1 = new Dictionary<string, string> { { "1", "張三" }, { "2", "李四" }, { "3", "張三" }, { "4", "張三" } }; var list2 = new Dictionary<string, string> { { "1", "張三" }, { "2", "李四" }, { "3", "李四" }, { "4", "張三" } }; //查詢表達式 var obj1 = from l1 in list1 join l2 in list2 on l1.Key equals l2.Key select new { l1, l2 }; //點標記 var obj = list1.Join(list2, l1 => l1.Key, l2 => l2.Key, (l1, l2) => new { l1, l2 });
例二:
點標記需要區分OrderBy、ThenBy有沒有覺得麻煩
//查詢表達式 var obj1 = from l1 in list1 join l2 in list2 on l1.Key equals l2.Key orderby l1.Key, l2.Key descending select new { l1, l2 }; //點標記 var obj = list1.Join(list2, l1 => l1.Key, l2 => l2.Key, (l1, l2) => new { l1, l2 }) .OrderBy(li => li.l1.Key) .ThenByDescending(li => li.l2.Key) .Select(t => new { t.l1, t.l2 });
總覺得查詢表達式更多的只是為了照顧那些寫慣了sql的程式員。
聯接查詢(內聯、左聯、交叉聯)
關於聯接查詢使用查詢表達式會更合適一些這個上面已經說了。
接下來我們寫內聯、左聯、交叉聯的查詢表達式和對應的點標記代碼。(目的:可能有些人不會,同時在這裡也給自己做個備忘)
內聯:
左聯:
交叉聯:
其實關於聯接查詢,如果EF建好了主外鍵我還是覺得點標記用起來更爽爽的。
總結:
本文並不是要改變你的習慣,也不是否定你的觀點。僅僅只是表達個人對點標記和查詢表達式的些許理解。
關於是使用查詢表達式還是點標記,可能起著更大決定性的作用的是團隊共同的習慣和規範。
然後還想說說,只要我們對比什麼,很可能就會有人跳出了,什麼不要比,用好了都一樣,什麼什麼才是最重要的,什麼什麼的。。。
就像很多人會反感java和C#的對比,其實我個人覺得對比下底層實現、對比下語法簡易也不是不可以的,只要我們可以從中學到知識(個人也是不喜歡對比 誰誰誰學什麼工資多少多少)。
昨天的自己對比今天的自己,今天的自己對比明天的自己。只要可以進步為什麼不要對比呢?
文章首鏈:http://www.cnblogs.com/zhaopei/p/5746414.html
感謝您的閱讀。如果文章對您有用,那麼請輕輕點個贊,以資鼓勵。