2017-08-16 140 views
8

我读实体框架的核心2.0 https://blogs.msdn.microsoft.com/dotnet/2017/08/14/announcing-entity-framework-core-2-0/实体框架EF.Functions.Like VS string.Contains

宣布它说,他们增加了新的SQL功能,如EF.Functions.Like用于执行SQL LIKE操作。

我在想,那么EF.Functions.Likestring.Contains/StartsWith之间的区别是什么呢?

例如:

var customers = context.Customers.Where(c => c.Name.StartsWith("a")); // Version A 
var customers = context.Customers.Where(c => EF.Functions.Like(c.Name, "a%")); // Version B 

什么是两个版本之间的区别? EF已经知道如何将string.Contains/StartsWith转换为相应的SQL操作,不​​是吗?

我能想到的唯一理由是,EF.Functions.Like将允许更复杂的模式,比如"a%b%"(虽然这其中可写为StartsWith("a") && Contains("b")

这是什么原因?

+3

检查SQL语句。最有可能的是,它们是相同的。 '.StartsWith'被转换为'LIKE'a%''。 *包含*另一方面将被转换为'LIKE'%a%'',这是一个非常糟糕的主意。 'LIKE'%''可以利用索引,因为它本质上是一个范围搜索。 'LIKE'%a%''虽然必须处理所有行以查找模式是否匹配 –

+1

是的,多数民众赞成在 –

+0

是的,这是我怀疑,它会更好,如果他们提供了一个扩展方法它,c.Name.Like(...) – areller

回答

10

与查询支持wildcard characters一样,因此与某些场景中的字符串扩展方法相比非常有用。

对于例如:如果我们搜索所有4个字母与“里”的名字作为中间人物,我们可以做EF.Functions.Like(c.Name, "_ri_");

,或者从城市让所有的客户与元音开始:

var customers = from c in context.Customers 
        where EF.Functions.Like(c.City, "[aeiou]%"); 
        select c; 
+0

上遇到了StartsWith/Containts函数的问题好吧,这很有道理。 谢谢你的详细答案。 – areller

+2

另外考虑阅读[#474查询:改善字符串的StartsWith,EndsWith和Contains的翻译](https://github.com/aspnet/EntityFramework/issues/474)线程的灵活性原因不在此决定背后。 –

9

@adiga的答案相当不完整,仅涵盖了使用情况差异的一部分。

但是,.StartsWith(...),.Contains(...).EndsWith(...)也被不同地翻译成SQL,然后EF.Functions.Like

例如.StartsWith被翻译为(string LIKE pattern + "%" AND CHARINDEX(pattern, string) = 1) OR pattern = ''其中.Contains被翻译成(CHARINDEX(pattern, string) > 0) OR pattern = ''

EF.Functions.Like然而被翻译成string LIKE pattern [ESCAPE escapeChar]

这也可能对性能有影响。以上内容适用于EF Core SqlServer提供程序。其他EF Core提供商可能会对其进行不同的翻译