web-dev-qa-db-ja.com

RemoveRange()による行の一括削除

テーブルから複数の行を削除しようとしています。

通常のSQL Serverでは、これは次のように簡単です。

_DELETE FROM Table
WHERE
    Table.Column = 'SomeRandomValue'
    AND Table.Column2 = 'AnotherRandomValue'
_

Entity Framework 6では、 RemoveRange() メソッドが導入されています。
ただし、使用した場合、Entity Frameworkは、指定したwhere句を使用して行を削除するのではなく、データベースにクエリを実行して、where句に一致するすべての行を取得し、主キーを使用して1つずつ削除します。

これはEntityFrameworkの現在の制限ですか?または、RemoveRange()を間違って使用していますか?

以下は、RemoveRange()の使用方法です。

_db.Tables.RemoveRange(
    db.Tables
        .Where(_ => _.Column == 'SomeRandomValue'
            && _.Column2 == 'AnotherRandomValue')
);
_
24
Peter Han

EFの制限に達したと思います。パフォーマンスを維持するために ExecuteSqlCommand を使用する必要がある場合があります。

3
Adi

探しているのは、エンティティをロードせずにLINQクエリからデータベース内の複数のレコードを削除するバッチ削除ライブラリです。

この機能をサポートする複数のライブラリが存在します。

リストはここにあります: Entity Framework Ba​​tch Delete Library

免責事項:私はプロジェクトの所有者です Entity Framework Plus

// using Z.EntityFramework.Plus; // Don't forget to include this.

// DELETE directly in SQL (without loading entities)
db.Tables.Where(_ => _.Column == 'SomeRandomValue'
                     && _.Column2 == 'AnotherRandomValue')
         .Delete();

// DELETE using a BatchSize      
db.Tables.Where(_ => _.Column == 'SomeRandomValue'
                     && _.Column2 == 'AnotherRandomValue')
         .Delete(x => x.BatchSize = 1000);

Wiki: EF +一括削除

5
Jonathan Magnan
var db1 =  db.Tables
        .Where(_ => _.Column == 'SomeRandomValue'
            && _.Column2 == 'AnotherRandomeValue').AsEnumerable().ToList();
db.Tables.RemoveRange(db1);
db.SaveChanges();

変数を使用してリムーバブルリストを格納し、それをRemoveRange()に渡します。

私は通常、このようにします。それが仕事です。これもあなたのケースでうまくいくことを願っています。

1
AKASH

少し壊れています、試してください

db.Tables.RemoveRange(
    db.Tables
        .Where(_ => _.Column == 'SomeRandomValue'
            && _.Column2 == 'AnotherRandomeValue').AsEnumerable().ToList()
);
db.SaveChanges();
1
TFD

私はこれを自分で処理していて、Adiに同意します-SQLを使用するだけです。

ログテーブルの古い行をクリーンアップしています。EFRemoveRangeがこれと同じことを行うのに、3秒で3分かかりました。

DELETE FROM LogEntries WHERE DATEDIFF(day, GETDATE(), Date) < -6

日付は、日付を含む列の名前です。もちろん、それを正しくするために、次のようにパラメーターを使用します。

  context.Database.ExecuteSqlCommand
      ("DELETE FROM  LogEntries WHERE DATEDIFF(day, GETDATE(), Date) < @DaysOld", new System.Data.SqlClient.SqlParameter(
                        "DaysOld", - Settings.DaysToKeepDBLogEntries));

私のケースには多くの行が関係していることに注意してください。私がプロジェクトを開始したとき、データが多くなかったとき、RemoveRangeは正常に機能しました。

0
user7369569

一歩下がって考えてください。それらを削除するためにデータベースからレコードを本当にダウンロードしますか?あなたができるからといってそれを良い考えにすることはできません。

おそらく、ストアドプロシージャを使用してデータベースからアイテムを削除することを検討できますか? EFはそれを行うこともできます...

0

私もこの問題に遭遇しました、これはLoreSoft(nugetパッケージマネージャーから取得できます)によってentityframework.extendedと呼ばれるライブラリでの私の回避策です:

1.まず、あなたのリストをクエリします。 2.次に、.extendedライブラリの関数である.Delete()を使用します。

var removeList = db.table.Where(_ => _.Column == 'SomeRandomValue'&& _.Column2 == 'AnotherRandomValue')        
removeList .Delete();

注: Entity Framework EF extended によると、執筆時点では、このentityframework.extendedは非推奨です。したがって、エンティティフレームワークとライブラリを考慮する必要があるかもしれません。 plus拡張子でテストしていませんが、.extendedライブラリを使用して動作することを確認できます。

0
csamleong

データベースへのアダプタを用意して、例のように適切な削除コマンドを送信しないのはなぜですか?

0
Shar1er80