web-dev-qa-db-ja.com

LINQ to Entitiesでの一括削除

LINQまたはLINQ-to-Entitiesの特定のクエリに一致する多数のオブジェクトを一括削除する方法はありますか?私が見つけることができる唯一の参照は古くなっており、削除したいすべてのオブジェクトを繰り返して手動で削除するのはばかげているようです。

79

問題は古いものです(EF5が存在する前から)。 EF5を使用している場合、 EntityFramework.Extended はこれを簡単に行います。

30
Shaul Behr

しばらく前に、4部構成のブログシリーズ(パート 12 、および 4 )を作成しましたEntity Frameworkでの一括更新(1つのコマンドによる)。

このシリーズの焦点は更新でしたが、削除に関係する原則を間違いなく使用できます。

そのため、次のような記述ができるはずです。

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

query.Delete();

必要なのは、Delete()拡張メソッドを実装することだけです。方法に関するヒントについては、投稿シリーズを参照してください...

お役に立てれば

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

私がここで見ている答えはLinq to Sqlです

DeleteAllOnSubmitは、System.Data.LinqおよびLinq to SqlであるITableの一部です

これは、Entity Frameworkでは実行できません。

そのすべてを言ったが、私はまだ解決策を持っていませんが、私がそうするとき、投稿します

6
Phil Strong

EF6を使用しており、削除のために行SQLクエリを実行する場合:

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

クエリのすべてのレコードを削除するデータコンテキストの DeleteAllOnSubmit メソッドを知っています。多くのオブジェクトが削除されているため、基礎となる最適化が必要です。よくわかりません。

2
Hemant

どれほど効率的かはわかりませんが、次のようなものを試すことができます。

// 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();
2
Scott Anderson

私は次のようなことをします:

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
G Jeny Ramirez

削除を行うストアドプロシージャを記述して、LINQから呼び出すことができます。セットベースの削除は全体的に高速になる可能性がありますが、影響するレコードが多すぎるとロックの問題が発生する可能性があり、レコードのセットをループするハイブリッドが必要になる場合があります(一度に2000、おそらくサイズはデータベース設計によって異なりますが、2000はセットベースのデルテに時間がかかり、テーブルの他の使用に影響していることがわかった場合の開始場所)を削除します。

1
HLGEM

この例では、削除するレコードを取得し、それらを1つずつ結果セットに添付して、削除するように要求します。次に、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();
      } 
    }
1
Demodave

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();
1
Amin

RemoveRangeはEF6で導入され、オブジェクトのリストを削除できます。超簡単。

var origins= (from po in db.PermitOrigins where po.PermitID == thisPermit.PermitID select po).ToList();
db.PermitOrigins.RemoveRange(origins);
db.SaveChanges();
1
Jarrette
 context.Entity.Where(p => p.col== id)
               .ToList().ForEach(p => db.Entity.DeleteObject(p));

これらは、EFを使用してDBからレコードを削除する最速の方法です

1
Anurag Deokar