Я удаляю несколько элементов из таблицы, используя Entity Framework. Нет внешнего ключа / родительского объекта, поэтому я не могу справиться с этим с помощью OnDeleteCascade.
Прямо сейчас я делаю это:
var widgets = context.Widgets
.Where(w => w.WidgetId == widgetId);
foreach (Widget widget in widgets)
{
context.Widgets.DeleteObject(widget);
}
context.SaveChanges();
Это работает, но foreach вызывает меня. Я использую EF4, но я не хочу выполнять SQL. Я просто хочу убедиться, что я ничего не пропустил - это так хорошо, как получается, верно? Я могу абстрагировать его с помощью метода расширения или помощника, но где-то мы все еще будем делать foreach, верно?
entity-framework
Джон Галлоуэй
источник
источник
Ответы:
Если вы не хотите выполнять SQL напрямую, вызов DeleteObject в цикле - это лучшее, что вы можете сделать сегодня.
Однако вы можете выполнить SQL и сделать его полностью универсальным с помощью метода расширения, используя подход, который я описал здесь .
Хотя этот ответ был для 3,5. Для 4.0 я бы, вероятно, использовал новый API-интерфейс ExecuteStoreCommand, вместо того, чтобы переходить к StoreConnection.
источник
EntityFramework 6 сделал это немного проще с
.RemoveRange()
.Пример:
источник
Ну, да, кроме того, что вы можете сделать это в два ряда:
источник
источник
WHERE IN ({0})
, и тогда второй аргумент должен бытьString.Join(",", idList)
.EntityFramework.Extended
String.Join
, вам может потребоваться использоватьstring.Format
и передать уже сформированную строку SQL в команду. Пока в вашем списке только целые числа, нет риска инъекционной атаки. Проверьте этот вопрос: как я могу передать массив команде execute store?Я знаю, что уже поздно, но если кому-то нужно простое решение, круто то, что вы также можете добавить к нему предложение where:
Примечание: только что протестировано с MSSQL2008.
Обновить:
Приведенное выше решение не будет работать, когда EF генерирует SQL-оператор с параметрами , поэтому вот обновление для EF5 :
Это требует немного размышлений, но работает хорошо.
источник
Для тех, кто использует EF5, может быть использована следующая библиотека расширений: https://github.com/loresoft/EntityFramework.Extended
источник
Delete()
функции в моих сущностях в EF6.context.Widgets.Where(w => w.WidgetId == widgetId).Delete();
это новый способ с EntityFramework.ExtendedТем не менее, кажется сумасшедшим, что приходится что-то вытаскивать с сервера только для того, чтобы удалить его, но, по крайней мере, вернуть только идентификаторы намного проще, чем сносить полные сущности:
источник
Widget
пройти проверку сущности Entity Framework, поскольку ваши объекты- заглушки имеют только инициализированноеId
свойство. Способ обойти это использоватьcontext.Configuration.ValidateOnSaveEnabled = false
(по крайней мере, в EF6). Это отключает собственную проверку Entity Framework, но, конечно, выполняет собственную проверку базы данных.delete
аналогичный обходной путь для созданияupdate
сущностей без их загрузки.EF 6.1
Использование:
источник
Для EF 4.1
источник
Для этого вы можете использовать библиотеки расширений, такие как EntityFramework.Extended или Z.EntityFramework.Plus.EF6, которые доступны для EF 5, 6 или Core. Эти библиотеки имеют отличную производительность, когда вам нужно удалить или обновить, и они используют LINQ. Пример для удаления ( источник плюс ):
ctx.Users.Where(x => x.LastLoginDate < DateTime.Now.AddYears(-2)) .Delete();
или ( источник расширен )
context.Users.Where(u => u.FirstName == "firstname") .Delete();
В них используются нативные операторы SQL, поэтому производительность великолепна.
источник
Самый быстрый способ удалить это использовать хранимую процедуру. Я предпочитаю хранимые процедуры в проекте базы данных, а не динамический SQL, потому что переименования будут обрабатываться правильно и иметь ошибки компилятора. Динамический SQL может ссылаться на таблицы, которые были удалены / переименованы, вызывая ошибки во время выполнения.
В этом примере у меня есть две таблицы List и ListItems. Мне нужен быстрый способ удалить все элементы списка данного списка.
Теперь интересная часть удаления элементов и обновления Entity Framework с использованием расширения.
Основной код теперь можно использовать как
источник
Если вы хотите удалить все строки таблицы, вы можете выполнить команду sql
TRUNCATE TABLE (Transact-SQL) Удаляет все строки из таблицы без регистрации удалений отдельных строк. TRUNCATE TABLE похож на оператор DELETE без предложения WHERE; однако TRUNCATE TABLE работает быстрее и использует меньше ресурсов системы и журнала транзакций.
источник
truncate table
с таблицами, на которые ссылается ограничение FOREIGN KEY. (Вы можете усечь таблицу с внешним ключом, который ссылается на себя.). Документация MSDNUUHHIVS
Это очень элегантный и быстрый способ удаления пакетов, но его следует использовать с осторожностью:context.SaveChanges()
Эти проблемы можно обойти, взяв под контроль транзакцию. Следующий код иллюстрирует, как пакетное удаление и массовая вставка транзакционным способом:
источник
Entity Framework Core
Резюме :
Замечания :
источник
Вы можете выполнять SQL-запросы напрямую следующим образом:
Для выбора мы можем использовать
источник
Вы также можете использовать метод DeleteAllOnSubmit () , передав его результаты в общий список, а не в var. Таким образом, ваш foreach сводится к одной строке кода:
Вероятно, он все еще использует цикл внутри.
источник
var
такое.Ответ Тана работал лучше всего для меня. Удалил все мои записи за одну поездку на сервер. Я боролся с фактическим вызовом метода расширения, поэтому думал, что поделюсь своим (EF 6):
Я добавил метод расширения к вспомогательному классу в своем проекте MVC и изменил имя на «RemoveWhere». Я вставляю dbContext в мои контроллеры, но вы также можете сделать
using
.Это сгенерировало один оператор удаления для группы.
источник
EF 6. =>
источник
Лучший :
in EF6 => .RemoveRange()
Пример:
источник
Смотрите ответ «любимый кусочек кода», который работает
Вот как я это использовал:
источник
В EF 6.2 это работает отлично, отправляя удаление непосредственно в базу данных без предварительной загрузки сущностей:
С фиксированным предикатом это довольно просто:
И если вам нужен динамический предикат, взгляните на LINQKit (доступен пакет Nuget), в моем случае что-то вроде этого работает нормально:
источник
Z.EntityFramework.Plus
или что-то подобное? ( entityframework.net/batch-delete )Delete()
метод по существу не существует).