Entity framework EF.Functions.Like vs string.Contains
Я читал анонс сущности framework core 2.0 https://blogs.msdn.microsoft.com/dotnet/2017/08/14/announcing-entity-framework-core-2-0/
В нем говорится, что они добавили новые функции Sql, такие как EF.Functions.Like
для выполнения операции SQL LIKE
.
Мне было интересно, что тогда будет разница между EF.Functions.Like
и string.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")
)
Это причина?
Ответы
Ответ 1
Подобный запрос поддерживает символы подстановки и, следовательно, очень полезен по сравнению с методами расширения строк в некоторых сценариях.
Например: если бы мы искали все 4-буквенные имена с 'ri' в качестве средних символов, мы могли бы сделать EF.Functions.Like(c.Name, "_ri_");
или чтобы получить всех клиентов из городов, которые начинаются с гласных:
var customers = from c in context.Customers
where EF.Functions.Like(c.City, "[aeiou]%");
select c;
(Пожалуйста, прочитайте ответ @Tseng о том, как они по-разному переводятся в запросы SQL)
Ответ 2
Ответ @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 могут переводить его по-другому.