簡體   English   中英

Linq查詢的行為不符合預期

[英]Linq query not behaving as expected

我有一個非常簡單的linq查詢,如下所示:

var result = (from r in employeeRepo.GetAll()
              where r.EmployeeName.Contains(searchString) 
                    || r.SAMAccountName.Contains(searchString)
              orderby r.EmployeeName
              select new SelectListItem 
              { 
                  Text = r.EmployeeName, 
                  Value = r.EmployeeName 
              });

這個問題是出於一些奇怪的原因,它把我搜索的每個人的記錄都記錄下來,無論是小寫還是大寫。

  1. 測試用戶
  2. 測試用戶
  3. 測試用戶

我會找回正確的記錄。 然而,當我使用小寫字母搜索我自己的名字時,我沒有得到任何結果,但如果我使用我的名字的第一個字母作為大寫,那么我得到結果。 我似乎無法弄清楚為什么這樣做。

數據庫中的每個名字和姓氏都以大寫字母開頭。

我正在使用的searchString是:

  1. richard - 我得到了正確的結果
  2. waidande - 未找到結果

上述兩個用戶都在數據庫中。

我也在使用Entity Framework來查詢Sql Server 2012

如果您的文本具有NVARCHAR數據類型,請檢查實際上不相同的類似字母:

CREATE TABLE #employee (ID INT IDENTITY(1,1), EmployeeName NVARCHAR(100));

INSERT INTO #employee(EmployeeName) VALUES (N'waidаnde');

SELECT *
FROM #employee
WHERE EmployeeName LIKE '%waidande%';

-- checking
SELECT *
FROM #employee
WHERE CAST(EmployeeName AS VARCHAR(100)) <> EmployeeName;

db <>小提琴演示

這里: 'а' != 'a' 一個來自Cyrillic 'a' ,第二個是正常的。


想法取自:

在此輸入圖像描述

幻燈片: http//sqlbits.com/Sessions/Event12/Revenge_The_SQL

PS我強烈建議觀看Rob Volk的演講: Revenge: The SQL!

要解決此問題,請確定問題是在EF端還是在DB端。 一個常見的錯誤是額外的空格,所以在繼續之前確保不是這種情況。

首先檢查EF生成的查詢,您可以使用以下方法之一來執行此操作

  1. ObjectQuery.ToTraceString()方法
  2. 攔截數據庫調用的EF日志記錄
  3. Sql server profiler

如果您正確使用EF並且您的查詢按預期轉換為SQL並且在where部分中包含謂詞,但您仍然沒有獲得任何有意義的結果,這里有一些想法在DB端嘗試:

  1. 檢查排序規則 (請注意,可以在服務器,數據庫和單個列級別設置) - 注意區分大小寫和正在使用的代碼頁
  2. 驗證您的搜索字符串是否包含可在db代碼頁中解釋的符號 - 例如,如果代碼頁為252 - Windows Latin 1 ANSI並且您發送的輸入包含來自UTF-16的符號超出ANSI范圍 - 您將無法獲得任何結果,即使符號看起來相同
  3. 非常不可能的,但作為最后檢查,如果你的查詢中的一個還沒有被緩存,描述在這里

默認情況下,SQL Server 2012(SQL Server)安裝時使用不區分大小寫的排序規則。 如果需要使用區分大小寫從數據庫中檢索記錄(因為您有“幾個”記錄),則需要更改排序規則(請注意,因為如果更改DBMS排序規則,則還會更改主數據庫排序規則,因此表和字段名稱也會變為大小寫敏感)。
如果您不需要避免從DBMS中檢索所有記錄,則可以在檢索后過濾記錄,即

var result = (from r in employeeRepo.GetAll()
          where r.EmployeeName.Contains(searchString) 
                || r.SAMAccountName.Contains(searchString)
          orderby r.EmployeeName
          select new SelectListItem 
          { 
              Text = r.EmployeeName, 
              Value = r.EmployeeName 
          })
          .ToList()  // Materialize records and apply case sensitive filter
          .Where(r.EmployeeName.Contains(searchString) 
                || r.SAMAccountName.Contains(searchString));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM