当我用Linq写实体
时context.MyTable.Where(t => t.Name == "Test");
它转换为以下sql:
select * from MyTable where Name = 'Test'
我想在Linq中将表达式写入将转换为:
的实体select * from MyTable where Name like 'Test'
有没有办法实现这个目标?
注意 - 我也尝试了Equals
和CompareTo == 0
,但无济于事。
我想使用Like
而不是=
的原因是因为如果您使用=
,则会在字符串末尾忽略空格,但如果使用Like
您使用Contains/StartsWith/EndsWith
(请参阅此问题:Why the SQL Server ignore the empty space at the end automatically?,以及:Linq to Entity comparing strings ignores white spaces)。
这个问题要求%,这可以用SqlMethods.Like
完成,但这不是同一个问题,我想要完全平等,所以这些对我没有帮助。
虽然使用context.MyTable.Where(t => SqlMethods.Like(t.Name, "Test")
,但这个问题确实看起来很有希望,所以我尝试了
dbWriteTable
但我收到以下错误:
{“LINQ to Entities无法识别方法'Boolean Like(System.String,System.String)'方法,并且此方法无法转换为商店表达式。”}
答案 0 :(得分:4)
这是official:
SQL Server遵循ANSI / ISO SQL-92规范(第8.2节,一般规则#3),介绍如何将字符串与空格进行比较。
如果你不想要它,那就太麻烦了。
一个不忽略空格的SQL函数是DATALENGTH
。幸运的是,我们可以在EF查询中使用此函数,因为它是SqlFunctions
中的一个函数。因此,您可以添加额外检查DATALENGTH
是否等于搜索字符串的长度:
var searchText = "Test";
var result = context.MyTable
.Where(t => t.Name == searchText
&& SqlFunctions.DataLength(t.Name)
== SqlFunctions.DataLength(searchText))
比较DataLength
和t.Name
的{{1}}是必要的,因为searchText
会返回字节数,而不是字符数(Ivan,感谢您的评论)。< / p>
答案 1 :(得分:2)
有趣的是,我写了原始问题的答案,并同意这个边缘案例并不重复。
根据您的查询结果大小,您是否可以运行第二个客户端传递:
var result = iQueryableSource
.Where(i => i.Field.Contains("Fred"))
.AsEnumerable()
.Where(i => i.Field == "Fred");
我同意,如果您的数据集很大,这可能是一个问题。
完全是服务器端的另一种方法是组合StartsWith和EndsWith:
var result = iQueryableSource
.Where(i => i.Field.StartsWith("Fred"))
.Where(i => i.Field.EndsWith("Fred");