实体框架(Core 2.0.2)翻译
.Where(t => t.Name.StartsWith(term))
进入这个SQL
([t].[Name] LIKE @__term_1 + N''%'' AND (LEFT([t].[Name], LEN(@__term_1)) = @__term_1))
不要左右部分(由AND
拆分的SQL)做同样的事情,并且每个部分都可以独立使用吗?
答案 0 :(得分:2)
以下EF Core问题跟踪器主题可以阐明为什么以这种方式实现它 - Query: Improve translation of String's StartsWith, EndsWith and Contains #474 。以下是一些重要的摘录:
我们在Relational包中使用的方法
Contains
,EndsWith
和StartsWith
的Linq翻译使用LIKE
运算符,如果值参数可能返回不正确的结果(什么我们正在搜索)包含通配符,例如'%'或者' _'。
然后
一般情况下,对于
LIKE
效果不佳的情况,我们可以回退到不依赖LIKE
的其他翻译,例如String.StartsWith()
:
var underscoreAThings = Things.Where(t => t.Name.StartsWith(t.Prefix));
SELECT * FROM Things WHERE CHARINDEX(Prefix, Name) = 1 OR Prefix='';
请注意,
CHARINDEX()
不匹配空字符串,但String.StartsWith("")
始终返回true,这就是我们添加前缀='''条件。 这种翻译的主要缺点是它不易被攻击。这可以通过混合翻译来解决,例如:
SELECT * FROM Things WHERE Name LIKE Prefix+'%' AND (CHARINDEX(Prefix, Name) = 1 OR Prefix = '');
很快,通过当前的翻译,它们可以解决SQL查询的可扩展性以及CLR string.StartsWith
方法的兼容性问题。在EF Core开发的不同阶段,他们只使用第一种或第二种方法,最后采用这种混合方法。