エンティティフレームワーク.Remove()と.DeleteObject()


141

次の2つの方法を使用すると、EFを使用してデータベースからアイテムを削除できます。

1つ目はにEntityCollectionあり、2つ目はにありObjectContextます。

それぞれいつ使用する必要がありますか?

一方が他方よりも好まれますか?

Remove()を返し、boolDeleteObject()返しますvoid

回答:


275

両方の方法で「データベースからアイテムを削除」できることは、一般的に正しくありません。正確には次のようになります。

  • ObjectContext.DeleteObject(entity)エンティティをDeletedコンテキスト内としてマークます。(それはだEntityStateDeleted呼び出す場合は、その後。)SaveChangesその後EFは、SQLの送信DELETEデータベースに文を。データベースの参照制約に違反していない場合、エンティティは削除されます。違反していない場合は、例外がスローされます。

  • EntityCollection.Remove(childEntity)親との関係をchildEntityDeletedマークます。場合はchildEntity、それ自体がデータベースから削除し、何を呼び出すときに正確に起こることはされてSaveChanges両者の関係の種類によって異なります。

    • 関係がオプションである場合、つまり、データベースの子から親を参照する外部キーでNULL値が許可されている場合、この外部はnullに設定され、SaveChangesこのNULL値を呼び出すchildEntityと、データベースに書き込まれます(つまり、 2つは削除されます)。これはSQL UPDATEステートメントで発生します。DELETEステートメントは発生しません。

    • 関係が必要で(FKはNULL値を許可しない)、関係が識別されない(つまり、外部キーが子の(複合)主キーの一部ではない)場合は、子を別の親に追加するか、子を明示的に削除する必要があります(DeleteObjectその場合)。これらのいずれも行わないと、参照制約に違反し、呼び出し時にEFが例外をスローしますSaveChanges-悪名高い1つ以上の外部キープロパティがnullにできないため、関係を変更できませんでした例外または同様。

    • 関係がされた場合の識別(それは必ずしもだ必要なプライマリキーのいずれかの部分ができないため、その後NULL)EFがマークされますchildEntityDeleted同様。SaveChangesSQL DELETEステートメントを呼び出すと、データベースに送信されます。データベース内の他の参照制約に違反していない場合、エンティティは削除されます。違反していない場合は、例外がスローされます。

私は実際に混乱ビット午前MSDNのページの備考セクションそれが言うので、あなたがリンクしている: " 関係は依存オブジェクトマークの関係および削除の依存オブジェクトの両方のRemoveメソッドを呼び出して、参照整合性制約がある場合。」上記の3つのケースにはすべて「参照整合性制約」があるため、これは不正確または間違っているように見えますが、最後のケースでのみ子が実際に削除されます。(ただし、「依存オブジェクト」とは、通常とは異なる用語になる識別関係に参加するオブジェクトを意味します。)


2
参照整合性ウィキペディア:参照整合性はデータのプロパティであり、満足すると、リレーション(テーブル)の1つの属性(列)のすべての値が別の(または同じ)リレーション(テーブル)の別の属性の値として存在する必要があります)、したがって、リレーションシップがオプションの場合、データ整合性ルール
Mohammadreza

3
@Mohammadreza:NULL「値ではない」と解釈する場合(「値NULL」を少しずさんに書いたことがあるのではなく)、「オプションの関係」は参照整合性の定義と矛盾しません。
スラウマ2014

1
では、EF CoreバージョンはObjectContext.DeleteObject何ですか?
ジョナサンアレン

13

Deletedを本当に使用したい場合は、外部キーをnullにできるようにする必要がありますが、結果として孤立したレコードが作成されます(これは、最初にそうすべきではない主な理由の1つです)。だから使うだけRemove()

ObjectContext.DeleteObject(entity)は、エンティティをコンテキストで削除済みとしてマークします。(その後、EntityStateが削除されます。)その後SaveChangesを呼び出すと、EFはSQL DELETEステートメントをデータベースに送信します。データベースの参照制約に違反していない場合、エンティティは削除されます。違反していない場合は、例外がスローされます。

EntityCollection.Remove(childEntity)は、親とchildEntityの関係を削除済みとしてマークします。childEntity自体がデータベースから削除され、SaveChangesを呼び出したときに正確に何が起こるかは、2つの間の関係の種類によって異なります。

注目に値することは、設定.State = EntityState.Deleted が自動的に検出された変更をトリガーしないことです。 アーカイブ


4
わかりました。私の回答に反対票を投じた人にとって、それはSlaumaの問題とは何の関係もありません。どちらも同じドキュメントを参照しています。私の理論はその一部ですが、鉱山は実際の例を説明します。
Matas Vaitkevicius
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.