拿字串A是否包含了字串B作為範例,這時候在SQL端(還沒產生成實體物件)時執行結果 跟 C#端(已從DB撈出資料)執行結果 就會發生不同的狀況。
先來看一Where下在資料還沒產生成實體物件的時候
C#:
var query = db.Table.Where(x => x.Name.Contains("abc")).ToList();SQL執行語法會是
SELECT[EmployeeId],[Name] FROM [dbo].[Employee] WHERE [Name] LIKE '%abc%'由此可見,資料判斷是在SQL端處理,然後把結果丟回到C#端。
再來是Where下在ToList()後面
C#:
var query = db.Table.ToList().Where(x => x.Name.Contains("abc"));SQL執行語法會是
SELECT[EmployeeId],[Name] FROM [dbo].[Employee]這時候變成了把所有Employee資料撈出來以後,在篩選資料。
一個是在SQL端下LIKE,一個是在C#端執行Contains,都是包含"abc",但是結果就會不一樣囉。
SQL的LIKE是不分辨大小寫的,所以"ABC"、"AbC"、"abc"、"abC"...都是會被認為是OK的資料。
但是在C#的Contains是有區分大小寫的,所以只有"abc"才會被篩選出來。
如果使用IndexOf去指定不區分大小寫,但是這個只能在C#端使用
錯誤的C#語法:
var query = db.Table.Where(x => x.Name.IndexOf("abc", StringComparison.CurrentCultureIgnoreCase) >= 0).ToList();這樣會報錯,因為LINQ在轉SQL語法的時候會發生不支援的情況,就回歸到一開始提到的Where時機。
所以我們要在取出資料後,由C#去執行篩選
C#語法:
var query = db.Table.ToList().Where(x => x.Name.IndexOf("abc", StringComparison.CurrentCultureIgnoreCase) >= 0);
PS:Contains是使用IndexOf去實做出來的,所以基本上IndexOf效能會略好於Contains
沒有留言 :
張貼留言