Comments 23
В Ef core 2.0 есть возможность мапить функции из коробки без необходимости расширять библиотеку.
http://anthonygiretti.com/2018/01/11/entity-framework-core-2-scalar-function-mapping/
Эта возможность есть и в Ef 6 platform кстати.
Плюс к вопросу. Никогда не замечал такого поведения. На 2.0 точно.
Так вот, помежуточные IQueryable выполняются до финального вызова ToList, причем EF Core это аргументирует в логах тем, что не может транслировать «некоторые выражения» и он вынужден выполнить запрос немедленно и далее уже работать с коллекцией в памяти.
Копание пока ничего не дало, есть старая закрытая issue github.com/aspnet/EntityFrameworkCore/issues/7096
Аналогично для Skip, Take. К примеру, warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'Skip(__p_3)' could not be translated and will be evaluated locally.
Можно же:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer(...)
.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));
}
Я имею ввиду вот такие случаи:
var list = dbContext.Persons.where(predicate).orderby(order);
if(filter.value.hasvalue)
{
list = list.where(f=>f.someField == filter.value);
}
Пришлось от такого избавиться и переставить сортировку в конце.
var list = dbContext.Persons.where(predicate);
if(filter.value.hasvalue)
{
list = list.where(f=>f.someField == filter.value);
}
list = list.orderby(order);
Ну что же, я рад чо у нас в linq2db это занимает ровно один чих:
github.com/linq2db/linq2db/blob/master/Source/LinqToDB/Sql/Sql.cs#L468
github.com/linq2db/linq2db/blob/master/Source/LinqToDB/Sql/Sql.cs#L103
Задумался, как написать поддержку такого метода расширения, как например
db.Goods.DeleteAsync(x => x.Price > 2000).
Не уверен, что это возможно. Такая функциональность противоречит идеологии фреймворка. Закрепление изменений происходит во время вызова метода SaveChanges()
. EF и EFC хранят граф объектов и следят за изменениями. По накопленным изменениям генерируются UPDATE
, INSERT
, DELETE
. Каким образом DeleteAsync превратится в граф объектов? Вы, конечно, можете написать простую логику:
- Загрузить все объекты
x.Price > 2000
- Удалить их. Но это будет ужасный оверхед.
Вообще, знающие люди говорят, что Bulk Operations и ORM это из разных областей.
linq2db.EntityFrameworkCore
В частности, entityframework-plus.net
— Delete without loading entities
— Update without loading entities
Я использую это в bulk actions.
Конечно же принципиально быстрее отрабатывает, без подгрузки записей.
Все ок, если принять и иметь в виду тот факт, что такие действия не обновляют загруженные в DbContext объекты.
Я провел некоторое время с их кодом, разбираясь как они интегрировались. Это печаль. К сожалению они уже закрыли сурцы, придется им дальше платить без оглядки.
Но если, все же, если я смог закласть зерна сомнения, попробуйте нашу итеграцию linq2db.EntityFrameworkCore. К релизу осталось пару дней, но пробовать можно уже.
К сожалению, localdb поставляется без лингвистических сервисов и подключить их не представляется возможным.
поясните пожалуйста, что это значит?
Реализуем свой оператор в Entity Framework Core