Tsql SQL Server是否会在查询时自动修剪nvarchar字段?

Tsql SQL Server是否会在查询时自动修剪nvarchar字段?,tsql,entity-framework-6,Tsql,Entity Framework 6,我有一个疑问: select '[' + p.Firstname + ']' from Person p where p.Firstname = 'Johanne' 在表中,我有多个人有这个名字,有些人在值上有一个尾随空格(值插入错误,将被更正) 那么,为什么这个查询会给我带来这个结果(我插入括号以显示空格): 这是配置问题吗?真正的查询来自EntityFramework6,但本例也会这样做。我怎样才能预防它 谢谢 编辑:我可以使用EF6和System.Data.Entity.SqlServe

我有一个疑问:

select '[' + p.Firstname + ']' from Person p
where p.Firstname = 'Johanne'
在表中,我有多个人有这个名字,有些人在值上有一个尾随空格(值插入错误,将被更正)

那么,为什么这个查询会给我带来这个结果(我插入括号以显示空格):

这是配置问题吗?真正的查询来自EntityFramework6,但本例也会这样做。我怎样才能预防它

谢谢

编辑:我可以使用EF6和
System.Data.Entity.SqlServer.SqlFunctions.DataLength
方法使其工作,如下所示:

ctx.Person.FirstOrDefault(p => p.FirstName == "Johanne" && SqlFunctions.DataLength(p.FirstName) == "Johanne".Length);

SQL Server遵循ANSI/ISO SQL-92规范(第8.2节,一般规则#3)中关于如何比较字符串和空格的规定。ANSI标准要求对比较中使用的字符串进行填充,以便它们的长度在比较之前匹配。填充直接影响WHERE和HAVING子句谓词以及其他Transact-SQL字符串比较的语义。例如,Transact-SQL认为字符串“abc”和“abc”对于大多数比较操作是等效的

此规则的唯一例外是LIKE谓词。如果LIKE谓词表达式的右侧具有一个尾随空格的值,则SQL Server不会在进行比较之前将这两个值填充到相同的长度。根据定义,LIKE谓词的目的是方便模式搜索,而不是简单的字符串相等性测试,因此这并不违反前面提到的ANSI SQL-92规范的部分


请参阅:

我不确定在EF中,但在TSQL中我使用DataLength

DataLength将返回包含尾随空格的长度
Len将返回不包括尾随空白的长度

and DataLength(p.Firstname) = Len('Johanne')  

您可以在Sql中创建一个新视图,并将该视图映射回EF对象。视图可以包含字段的长度,在selectusingdatalength中,您知道要匹配,然后可以在使用EF时在where子句中对其进行筛选。 或者,您可以创建一个Sql存储过程,该过程使用LIKE进行比较,而不使用通配符(这会产生所需的结果),并将其映射回您的代码,并在EF中的Where语句中调用它


使用视图

Create View MyCustomView
AS
SELECT [column1,column2,etc], DATALENGTH(FirstName) AS FirstNameLength
FROM Person
GO
那么您的EF将是:

Persons.Where(p => p.FirstNameLength == "Johanne".Length && p.FirstName == "Johanne");

使用存储的进程

CREATE PROCEDURE [dbo].[GetPersons]
firstName int = null
AS
BEGIN
SET NOCOUNT ON;
select [your fields here]
from persons
where FirstName like @firstName
END
在C#中,确保映射正确,然后

this.Database.SqlQuery<Person>("GetPersons","Johanne");
this.Database.SqlQuery(“GetPersons”、“Johanne”);


EF6还支持在执行sql之前在DbContext中直接编辑sql。在特定情况下,您可以开发一些自定义代码,将=替换为like,但在您这样做之前,首先尝试上面的代码可能更容易。

我注意到,如果where子句中的值是
'Johanne'
(末尾有一个空格),我仍然得到相同的结果。正确,但默认情况下,在Sql Server中,如果您有前导空格,则它将不匹配,即“Johanne”不会在where子句中返回任何结果。如果您使用
N'string here'
,例如
where p.Firstname=N'Johanne'
,它是否有效?
N
告诉它使用Unicode,这将与列的类型相匹配。@Igor我刚刚测试了它,我可以确认前导空格将阻止查询返回values@AndrewMorton,我刚刚测试了它,它产生了相同的输出。另请参见:感谢安东尼的解释!你知道我如何用EF6克服这个问题吗?我的意思是,如果我搜索value
'Johanne'
(带空格),我不想看到没有空格的值。根据我所读的内容,你应该能够使用like(一路阅读),但根据文章,要非常注意性能的影响。我还读到,EF“contains”在这样的情况下具有一定的重要性,并且在很大程度上是按照类似的方式运行的。参见EF中like的“实现”,我试过了,但这在我的案例中不起作用,Jon Skeet在回答中提出的在使用EF6时转换为
like%value%
,因此相同的值与前导或尾随空格匹配。那么.TrimEnd()呢?是的,我在TSQL中尝试了
数据长度
(成功)。然而,当我在EF6中使用
string.Length
时,它只会转换为
LEN
,我不知道如何让EF6使用
DataLength
,其中“['+p.Firstname+']='[Johanne]”我发现了一种使用
SqlFunctions
类更简单的方法,请参见我的编辑。但非常感谢您的解决方案,它们是很好的替代品!
this.Database.SqlQuery<Person>("GetPersons","Johanne");