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