10

I have a very simple linq query which is as following:

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 
              });

The issue is for some strange reason it fetches me the record of every person who I search for whether in lower case or upper case. i.e.

  1. test user
  2. Test User
  3. TEST USER

I will get back the correct records. However when I search for my own name using lower case I don't get any results back but if I use the first letter of my name as upper case then I get the results. I can't seem to figure out why its doing that.

Every first and last name in the database start with upper case.

The searchString which I'm using are:

  1. richard - I get correct results
  2. waidande - no results found

Both of the above users are in the database.

I'm also using Entity Framework to query Sql Server 2012.

Amir M
  • 508
  • 1
  • 8
  • 28
Izzy
  • 6,740
  • 7
  • 40
  • 84
  • Can you show the exact data and the value of `searchString` that does seem to do a case insensitive match and then the one that seems to do a case sensitive match. Also what is `employeeRepo`? Is it some type of Linq to SQL provider? – juharr Apr 01 '16 at 12:05
  • @juharr the one that matches is `richard` the one that doesnt match is `waidande` and `GetAll()` is `IEnumerable GetAll();` – Izzy Apr 01 '16 at 12:08
  • 5
    Can it be related with your SQL Server's case sensitivity settings? – Orkun Bekar Apr 01 '16 at 12:10
  • Please include the relevant data as well in your question. Specifically is there a "Richard" and "Waidande" values in your collection or DB. – juharr Apr 01 '16 at 12:10
  • @OrkunBekar but it works for everyone else but my name – Izzy Apr 01 '16 at 12:11
  • But what is `employeeRepo`? It's important to know if this is EF or not as Linq can behave completely differently if you are using a provider that's translating it to SQL versus running it in code. – juharr Apr 01 '16 at 12:11
  • @juharr sorry my bad `employeeRepo` is EF – Izzy Apr 01 '16 at 12:12
  • In that case as @OrkunBekar mentioned the DB will control case sensitivity. Though it's still not clear what is going on as you seem to be seeing both case insensitive and case sensitive comparisons. – juharr Apr 01 '16 at 12:14
  • @juharr How can I check the control case sensitivity on the DB? – Izzy Apr 01 '16 at 13:05
  • Here's a question about that for SQL Server. If you're using a different DB then I'm sure you can google for something similar. http://stackoverflow.com/questions/1411161/sql-server-check-case-sensitivity – juharr Apr 01 '16 at 13:06
  • 3
    Have you tried actually running a SQL query? It would be something like `Select * From EmployeeRepo Where EnployeeName Like '%richard%' Or SAMAccountName Like '%richard%'` Then copy and paste the other value in there to see what the results are. I doubt this is a case issue and more likely there are some special characters either in your DB or search string that are throwing it off. – juharr Apr 01 '16 at 13:12
  • Maybe for all but your own entry, the "SAMAccountName" contains the searchstring in all lowercase? – NineBerry Apr 03 '16 at 14:45
  • What DBMS do you use? – Orif Khodjaev Apr 03 '16 at 15:20
  • @OrifKhodjaev Using sql server 2012 – Izzy Apr 03 '16 at 17:28
  • 1
    *whether in lower case or upper case* - quite weird if, as you say, `GetAll()` is `IEnumerable GetAll();`, making this a plain .Net match. – Gert Arnold Apr 04 '16 at 17:36
  • 2
    Maybe this is your case [demo](https://data.stackexchange.com/stackoverflow/query/466238) – Lukasz Szozda Apr 04 '16 at 20:00
  • @lad2025 Yeah, or "waidаndе". The date of the question raises suspicions :) Are you going to give the clue? – Gert Arnold Apr 04 '16 at 21:11
  • @GertArnold The clue is very simple `а` != `a` :) – Lukasz Szozda Apr 05 '16 at 06:59
  • Just in case this may really be an issue the OP isn't aware of: @Izzy, any chance you have Cyrillic characters in there? – Gert Arnold Apr 05 '16 at 07:06
  • @GertArnold I've debugged through and the value that is being passed is `waidаndе` without any spaces or special characters – Izzy Apr 05 '16 at 07:30
  • The second 'а' and the 'е' are Cyrillic characters (code 1072 and 1077, in stead of the expected 97 and 101, respectively). – Gert Arnold Apr 05 '16 at 07:58
  • @lad2025 Are you going to compose an answer? it's your catch! – Gert Arnold Apr 05 '16 at 09:29
  • @GertArnold You should compose an answer as it's a very good catch and may help some of the future readers – Izzy Apr 05 '16 at 10:19
  • @Izzy, please note that my answer, which was here first :-) also contains the point about symbols looking the same, but having different code point - see point #2, so please mark my suggestion as answer as well – ironstone13 Apr 06 '16 at 15:00

3 Answers3

10

If your text has NVARCHAR datatype check for similiar letters that in reality are not the same:

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

Here: 'а' != 'a'. One is from Cyrillic 'a' and the second is normal.


Idea taken from:

enter image description here

Slide from: http://sqlbits.com/Sessions/Event12/Revenge_The_SQL

P.S. I highly recommend to watch Rob Volk's talk: Revenge: The SQL!.

Lukasz Szozda
  • 162,964
  • 23
  • 234
  • 275
6

To troubleshoot the issue, determine whether the problem is on the EF side, or on DB side. A common mistake is extra whitespace, so make sure it's not the case before proceeding.

First check what query is being generated by EF, you can use one of the following methods to do this

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

If you are using EF correctly and your query is translated to SQL as expected and contains the predicates in the where section, but you still are not getting any meaningful results, here are some ideas to try out on the DB side:

  1. Check collation ( be aware it can be set on server, database and individual column level) - beware of case sensitivity and code page that is being used
  2. Verify that your search string contains symbols that can be interpreted in the db code page - for example if code page is 252 - Windows Latin 1 ANSI and you are sending input with symbols from UTF-16 that are outside ANSI - you won't get any results, even though the symbols look the same
  3. Highly improbable, but as last resort check if one of your queries has not been cached, as described here
ironstone13
  • 3,325
  • 18
  • 24
1

SQL Server 2012 (SQL Server) is installed by default with case insensitive collation. If you need to retrieve records from the database using case sensitivity (because you have "several" records) you need to change the collation (take care because if you change DBMS collation you change also master database collation so also tables and field names become case sensitive).
If you don't need to avoid to retrieve all the records from the DBMS you can just filter records after you retrieve them, i.e.

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));
bubi
  • 6,414
  • 3
  • 28
  • 45