Linq表達式、Lambda表達式你更喜歡哪個?


什么是Linq表達式?什么是Lambda表達式?

如圖:

由此可見Linq表達式和Lambda表達式並沒有什么可比性

那與Lambda表達式相關的整條語句稱作什么呢?在微軟並沒有給出官方的命名,在《深入理解C#》中稱為點標記

查詢表達式、點標記你更喜歡哪個?

所以,我們的標題的提問根本就不合適。應該是“查詢表達式和點標記你更喜歡哪個?”。如:

 //查詢表達式
 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 });

為什么選擇點標記 

我相信更多的人偏向選擇點標記。具體什么原因我也說不清(可能是點標記中的Lambda更加優雅吧)。對於我個人來說,也是更加喜歡點標記這種方式。

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();
ListA.Distinct().ToList();//去重
ListA.Except(ListB).ToList();//差集
ListA.Union(ListB).ToList();  //並集
ListA.Intersect(ListB).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建好了主外鍵我還是覺得點標記用起來更爽爽的。

 

結束:

本文並不是要改變你的習慣,也不是否定你的觀點。僅僅只是表達個人對點標記和查詢表達式的些許理解。

關於是使用查詢表達式還是點標記,可能起着更大決定性的作用的是團隊共同的習慣和規范。

 

本文以同步至《C#基礎知識鞏固系列


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM