Entity Framework:从 SQL 开始
Entity Framework: StartsWith to SQL
Entity Framework(核心 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))
左右两部分(这个SQL被AND
分割的)不是一样的,不能各自独立使用吗?
以下 EF Core 问题跟踪线程可以阐明为什么以这种方式实现它 - Query: Improve translation of String's StartsWith, EndsWith and Contains #474 。以下是一些重要的摘录:
Linq translation for methods Contains
, EndsWith
and StartsWith
that we have in the Relational package uses LIKE
operator, which may return incorrect results if the value parameter (what we are searching for) contains wildcard characters, e.g. '%' or '_'.
然后
In general for cases in which LIKE
doesn't work well we can fall back to alternative translations that don't rely on LIKE
, e.g. for String.StartsWith()
:
var underscoreAThings = Things.Where(t => t.Name.StartsWith(t.Prefix));
SELECT * FROM Things WHERE CHARINDEX(Prefix, Name) = 1 OR Prefix='';
Note that CHARINDEX()
won't match an empty string but String.StartsWith("")
always return true, that's why we add the Prefix ='' condition.
The main disadvantage of this translation is that it is not sargable. That can be addressed with a hybrid translation, e.g.:
SELECT * FROM Things WHERE Name LIKE Prefix+'%' AND (CHARINDEX(Prefix, Name) = 1 OR Prefix = '');
很快,通过当前的翻译,他们解决了 SQL 查询可搜索性以及 CLR string.StartsWith
方法兼容性问题。在 EF Core 开发的不同阶段,他们只使用第一种或第二种方法,最后采用这种混合方法。
Entity Framework(核心 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))
左右两部分(这个SQL被AND
分割的)不是一样的,不能各自独立使用吗?
以下 EF Core 问题跟踪线程可以阐明为什么以这种方式实现它 - Query: Improve translation of String's StartsWith, EndsWith and Contains #474 。以下是一些重要的摘录:
Linq translation for methods
Contains
,EndsWith
andStartsWith
that we have in the Relational package usesLIKE
operator, which may return incorrect results if the value parameter (what we are searching for) contains wildcard characters, e.g. '%' or '_'.
然后
In general for cases in which
LIKE
doesn't work well we can fall back to alternative translations that don't rely onLIKE
, e.g. forString.StartsWith()
:
var underscoreAThings = Things.Where(t => t.Name.StartsWith(t.Prefix));
SELECT * FROM Things WHERE CHARINDEX(Prefix, Name) = 1 OR Prefix='';
Note that
CHARINDEX()
won't match an empty string butString.StartsWith("")
always return true, that's why we add the Prefix ='' condition. The main disadvantage of this translation is that it is not sargable. That can be addressed with a hybrid translation, e.g.:
SELECT * FROM Things WHERE Name LIKE Prefix+'%' AND (CHARINDEX(Prefix, Name) = 1 OR Prefix = '');
很快,通过当前的翻译,他们解决了 SQL 查询可搜索性以及 CLR string.StartsWith
方法兼容性问题。在 EF Core 开发的不同阶段,他们只使用第一种或第二种方法,最后采用这种混合方法。