实体框架:StartsWith to SQL

时间:2018-04-02 18:06:45

标签: entity-framework tsql linq-to-sql sql-like startswith

实体框架(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)做同样的事情,并且每个部分都可以独立使用吗?

1 个答案:

答案 0 :(得分:2)

以下EF Core问题跟踪器主题可以阐明为什么以这种方式实现它 - Query: Improve translation of String's StartsWith, EndsWith and Contains #474 。以下是一些重要的摘录:

  

我们在Relational包中使用的方法ContainsEndsWithStartsWith的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开发的不同阶段,他们只使用第一种或第二种方法,最后采用这种混合方法。