I have this query :
select '[' + p.Firstname + ']' from Person p where p.Firstname = 'Johanne'
In the table, I have multiple personne who have this firstname, and some have a trailing space on the value (bad insertion of the values, it will be corrected).
Why then does this query bring me this result (I inserted the brackets to visualize the spaces) :
[Johanne] [Johanne ] [Johanne ] [Johanne]
Is this a configuration thing ? The real query comes from entity framework 6, but this example does it also. How can I prevent it ?
Edit: I could make it work using EF6 and the
System.Data.Entity.SqlServer.SqlFunctions.DataLength method like this:
ctx.Person.FirstOrDefault(p => p.FirstName == "Johanne" && SqlFunctions.DataLength(p.FirstName) == "Johanne".Length);
SQL Server follows the ANSI/ISO SQL-92 specification (Section 8.2, , General rules #3) on how to compare strings with spaces. The ANSI standard requires padding for the character strings used in comparisons so that their lengths match before comparing them. The padding directly affects the semantics of WHERE and HAVING clause predicates and other Transact-SQL string comparisons. For example, Transact-SQL considers the strings 'abc' and 'abc ' to be equivalent for most comparison operations.
The only exception to this rule is the LIKE predicate. When the right side of a LIKE predicate expression features a value with a trailing space, SQL Server does not pad the two values to the same length before the comparison occurs. Because the purpose of the LIKE predicate, by definition, is to facilitate pattern searches rather than simple string equality tests, this does not violate the section of the ANSI SQL-92 specification mentioned earlier.
You could create a new view in Sql and map that view back to an EF object. The view could contain the length of the field(s), in the select using DataLength, you know you want to match against and then you could filter on that in your where clause when you use EF. Alternatively you could create a Sql Stored Proc that does a comparison using LIKE without wild cards (which produces the desired result) and map that back to your code and call it in your Where statement in EF.
Create View MyCustomView AS SELECT [column1,column2,etc], DATALENGTH(FirstName) AS FirstNameLength FROM Person GO
Then your EF would be:
Persons.Where(p => p.FirstNameLength == "Johanne".Length && p.FirstName == "Johanne");
To use a Stored Proc
CREATE PROCEDURE [dbo].[GetPersons] firstName int = null AS BEGIN SET NOCOUNT ON; select [your fields here] from persons where FirstName like @firstName END
In C# make sure your mapping is correct and then
EF6 also supports directly editing the sql in the DbContext before it is executed. You could develop some custom code that replaces the = with like under specific circumstances but maybe easier to try the above first before you do that.