【问题标题】:Linq query not behaving as expectedLinq 查询未按预期运行
【发布时间】:2016-04-01 12:00:09
【问题描述】:

我有一个非常简单的 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

【问题讨论】:

  • 您能否显示确切的数据和searchString 的值,它似乎进行了不区分大小写的匹配,然后是似乎进行了区分大小写的匹配。还有什么是employeeRepo?它是某种类型的 Linq to SQL 提供程序吗?
  • 会不会和你的SQL Server的区分大小写设置有关?
  • 您是否尝试过实际运行 SQL 查询?类似于Select * From EmployeeRepo Where EnployeeName Like '%richard%' Or SAMAccountName Like '%richard%' 然后复制并粘贴另一个值,看看结果是什么。我怀疑这是一个案例问题,更有可能在您的数据库或搜索字符串中存在一些特殊字符正在抛出它。
  • 无论是小写还是大写 - 如您所说,GetAll()IEnumerable<T> GetAll();,这很奇怪,这使得这是一个简单的 .Net 匹配。
  • 也许这是你的情况demo

标签: c# sql-server entity-framework linq sql-server-2012


【解决方案1】:

如果您的文本有 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<>fiddle demo

这里:'а' != 'a'。一个是来自Cyrillic'a',第二个是正常的。


创意来自:

幻灯片来自:http://sqlbits.com/Sessions/Event12/Revenge_The_SQL

附:我强烈推荐观看 Rob Volk 的演讲:Revenge: The SQL!

【讨论】:

    【解决方案2】:

    要解决问题,请确定问题出在 EF 端还是 DB 端。 一个常见的错误是多余的空格,所以在继续之前确保不是这种情况。

    首先检查EF正在生成什么查询,可以使用以下方法之一来做到这一点

    1. ObjectQuery.ToTraceString() method
    2. EF logging of intercepted db calls
    3. Sql server profiler

    如果您正确使用 EF 并且您的查询按预期转换为 SQL 并包含 where 部分中的谓词,但您仍然没有得到任何有意义的结果,这里有一些想法可以在 DB 端尝试:

    1. 检查collation(注意它可以在服务器、数据库和单个列级别上设置)-注意区分大小写和正在使用的代码页
    2. 验证您的搜索字符串是否包含可在 db 代码页中解释的符号 - 例如,如果代码页为 252 - Windows Latin 1 ANSI,并且您发送的输入包含 ANSI 之外的 UTF-16 符号 - 您赢了'没有得到任何结果,即使符号看起来一样
    3. 非常不可能,但作为最后的手段,请检查您的查询是否未被缓存,如 here 所述

    【讨论】:

      【解决方案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));
      

      【讨论】:

        猜你喜欢
        • 2021-06-07
        • 2012-05-20
        • 1970-01-01
        • 1970-01-01
        • 2016-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-13
        相关资源
        最近更新 更多