RemoveRangeがEntity FrameworkコアでInvalidOperationExceptionをスローする

c# entity-framework-core

質問

私はエラーが表示されます:

エンティティタイプ 'Pupil'のインスタンスは、同じキーを持つこのタイプの別のインスタンスがすでに追跡されているため、追跡できません。新しいエンティティを追加するとき、ほとんどのキータイプに対して、キーが設定されていない場合(つまり、キープロパティにそのタイプのデフォルト値が割り当てられている場合)、一意の一時キー値が作成されます。新しいエンティティのキ​​ー値を明示的に設定する場合は、既存のエンティティや他の新しいエンティティ用に生成された一時的な値と衝突しないようにしてください。既存のエンティティをアタッチする場合は、指定されたキー値を持つエンティティインスタンスが1つだけコンテキストにアタッチされていることを確認します。

このインスタンスの前に取得してコンテキストキャッシュにロードするとこのエラーは分かりますが、私は避けています!!!

    var pupilsToDelete = pupilIds.Select(id => new Pupil { Id = id });
    context.RemoveRange(pupilsToDelete.ToList());
    await context.SaveChangesAsync();

実行時には、瞳孔はすべて異なるIDです。

なぜ私はそのエラーを取得するのですか?

受け入れられた回答

レコードを削除するには、コンテキストから追跡可能である必要があります。したがって、 Pupil新しいコレクションを作成するのではなく、コンテキストから参照するだけです

 var pupilsToDelete = context.Pupils.Where(a => pupilIds.Contains(a.Id)).Select(b => b);
 context.Pupils.RemoveRange(pupilsToDelete);
 await context.SaveChangesAsync();

人気のある回答

レコードを削除するには、ObjectContextがレコードを追跡していることを確認する必要があります。アイテムを削除する最も良い方法は@Mostafizによって回答されますが、エンティティをコンテキストに添付することもできます。

var pupilsToDelete = pupilIds.Select(id => new Pupil { Id = id });
foreach(var p in pupilsToDelete )
   context.Attach(p);
context.RemoveRange(pupilsToDelete.ToList());
await context.SaveChangesAsync();

どちらが良いアプローチではない?



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ