Массовое удаление в LINQ to Entities


есть ли способ массового удаления группы объектов, соответствующих заданному запросу в LINQ или LINQ-to-Entities? Единственные ссылки, которые я могу найти, устарели, и кажется глупым перебирать и вручную удалять все объекты, которые я хочу удалить.

13 77

13 ответов:

вопрос старый (до того, как EF5 существовал). Для тех, кто использует EF5,EntityFramework.Расширенный это в оснастке.

некоторое время назад я написал серию блога из 4 частей (Parts 1,2,3 и 4) покрытие выполнения массовых обновлений (с одной командой) в Entity Framework.

хотя в центре внимания этой серии было обновление, вы определенно можете использовать принципы, связанные с удалением.

Так что вы должны быть в состоянии написать что-то вроде этого:

var query = from c in ctx.Customers
            where c.SalesPerson.Email == "..."
            select c;

query.Delete();

все, что вам нужно сделать, это реализовать метод расширения Delete (). Видеть после серии подсказок о том, как...

надеюсь, что это помогает

    using (var context = new DatabaseEntities())
    {
        // delete existing records
        context.ExecuteStoreCommand("DELETE FROM YOURTABLE WHERE CustomerID = {0}", customerId);
    }

ответы, которые я вижу здесь, - это Linq to Sql

DeleteAllOnSubmit является частью системы.Данные.Linq и ITable, который является Linq to Sql

Это не может быть сделано с Entity Framework.

сказав Все это, у меня еще нет решения, но я отправлю назад, когда я это сделаю

для тех, кто использует EF6 и хочет выполнить SQL-запрос строки для удаления:

using (var context = new DatabaseEntities())
{
    // delete existing records
    context.Database.ExecuteSqlCommand("DELETE FROM YOURTABLE WHERE CustomerID = @id", idParameter);
}

Я знаю DeleteAllOnSubmit метод любого контекста данных, который удалит все записи в запросе. Должна быть какая-то оптимизация, так как многие объекты удаляются. Хотя я не уверен.

Я не уверен, насколько эффективной она будет, но вы могли бы попробовать что-то вроде этого:

// deletes all "People" with the name "Joe"
var mypeople = from p in myDataContext.People
               where p.Name == "Joe";
               select p;
myDataContext.People.DeleteAllOnSubmit(mypeople);
myDataContext.SubmitChanges();

вы можете написать сохраненный proc, который выполняет удаление и вызывает его из LINQ. Удаление на основе набора, скорее всего, быстрее в целом, но если оно затрагивает слишком много записей, вы можете вызвать проблемы с блокировкой, и вам может понадобиться гибрид циклического перебора наборов записей (возможно, 2000 за раз, размер зависит от вашего дизайна базы данных, но 2000 является отправной точкой, если вы обнаружите, что delte на основе набора занимает так много времени, что это влияет на другое использование таблицы), чтобы сделать удаление.

удаление данных с помощью Entity Framework зависит от использования метода DeleteObject. Этот метод можно вызвать в коллекции EntityCollection для класса сущностей, который требуется удалить, или в производном ObjectContext. Вот простой пример:

NorthwindEntities db = new NorthwindEntities();

IEnumerable<Order_Detail> ods = from o in db.Order_Details
                                where o.OrderID == 12345                                    
                                select o;

foreach (Order_Detail od in ods) 
    db.Order_Details.DeleteObject(od);

db.SaveChanges();

Я бы сделал что-то вроде:

var recordsToDelete = (from c in db.Candidates_T where c.MyField == null select c).ToList<Candidates_T>();
if(recordsToDelete.Count > 0)
{
    foreach(var record in recordsToDelete)
    {
        db.Candidate_T.DeleteObject(record);
        db.SaveChanges();
    }
}   

Я не думаю, что есть способ сделать это без цикла, так как Entity Framework работает с сущностями и большую часть времени это означает сбор объектов.

в этом примере я получаю записи для удаления и один за другим прикрепляю их к набору результатов, а затем запрашиваю их удаление. Тогда у меня есть 1 сохранить изменения.

    using (BillingDB db = new BillingDB())
    {
      var recordsToDelete = (from i in db.sales_order_item
                  where i.sales_order_id == shoppingCartId
                  select i).ToList<sales_order_item>();

      if(recordsToDelete.Count > 0)
      {
        foreach (var deleteSalesOrderItem in recordsToDelete)
        {                  
            db.sales_order_item.Attach(deleteSalesOrderItem);
            db.sales_order_item.Remove(deleteSalesOrderItem);                  
        }
        db.SaveChanges();
      } 
    }
 context.Entity.Where(p => p.col== id)
               .ToList().ForEach(p => db.Entity.DeleteObject(p));

Это самый быстрый способ удалить запись из БД с помощью EF

RemoveRange был введен в EF6, он может удалить список объектов. Супер-легкий.

var origins= (from po in db.PermitOrigins where po.PermitID == thisPermit.PermitID select po).ToList();
db.PermitOrigins.RemoveRange(origins);
db.SaveChanges();