[Entity Framework與LINQ開發實戰] 資料類型為 nvarchar 或 nchar 在EF遇到的問題
最近在開發一個搜尋功能時,遇到一個條件一直搜尋不到的問題。
有經驗的人看到第一句話跟這篇的標題,也許就猜到是怎麼回事了,
但由於在ORM的情況下,有時沒有仔細去看資料庫的欄位型態,
只知道物件的型態。因此遇到時還真的會愣了一下。
其實這個問題並不屬於EF的問題,但算是使用ORM技術時,需要注意的小地方吧。
首先我開了一個測試Table,只有簡單的兩個欄位,除了PK外,另一個是nchar(10)型態
資料
(偉榮大強烈建議我要說明:上方資料"序號"欄位後面是有空白的,只是在上方看不出來。)
接下來的部分,我用LinqPad載入包含edmx的dll來做Demo
請看一下上圖,在兩個搜尋條件中,得到的答案會是什麼‧
結果是
看到這個結果,在不知道資料庫原始欄位的型態情況下,真的會想揉揉眼睛。
由於 nvarchar 、varchar 與 nchar 、char的差別
在於前者是可變長度,後者是固定長度。(有n的代表支援Unicode)
因此在此例中,如果去算序號這個欄位的長度的話,算出來都會是 10 。
但為何在ToList()跟沒有的結果會有差別呢?
因為ToList()之後,對資料的搜尋就是對List集合的搜尋,
因此實際的資料是 "1111 " ,而下的條件為"1111"。所以第一個搜尋結果為False。
補充:有興趣的可以看一下這篇 SET ANSI_PADDING (Transact-SQL)
而第二條語法則是經由EF的Provider產出SQL語法在資料庫做查詢,
而資料庫對於這樣的搜尋有特別處理,請看下圖:
上圖前兩條語法,不管是"1111"或"1111 "都搜尋的到。
而" 1111"則搜尋不到。
我想SQL在搜尋時,會將搜尋條件補足或截斷後面的空白直到兩者相同長度,因此前兩條才會為True吧。
(關於上面這句話我沒有搜尋到官方文件,因此只是我的臆測。如果有的話麻煩分享一下,謝謝。)
算是一個小眉角,如果沒仔細看資料庫很容易忽略掉,
因此享受ORM的優點同時,資料庫的基本觀念還是不能少的~