144

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

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

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

どちらかが優先されますか?

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

4

2 に答える 2

281

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

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

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

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

    • 関係が必要であり(FK は値を許可しないNULL)、関係が識別されない(つまり、外部キーが子の (複合) 主キーの一部ではない) 場合は、子を別の親に追加するか、子を明示的に削除する必要があります(DeleteObjectthenで)。これらのいずれも行わないと、参照制約に違反し、EF は呼び出し時に例外SaveChangesスローします似ている。

    • 関係が識別されている場合(主キーのどの部分も にすることができないため、必然的に必要NULLになります) EF も同様にマークchildEntityDeletedます。SaveChangesSQLDELETEステートメントを呼び出すと、データベースに送信されます。データベース内の他の参照制約に違反していない場合、エンティティは削除されます。それ以外の場合は、例外がスローされます。

あなたがリンクした MSDN ページの備考セクションについて、実際には少し混乱しています。 "。上記の3つのケースすべてに「参照整合性制約」があるため、これは不正確または間違っているように思えますが、最後のケースでのみ子が実際に削除されます。(ただし、「依存オブジェクト」とは、珍しい用語である識別関係に参加するオブジェクトを意味する場合を除きます。)

于 2013-07-18T14:33:13.163 に答える
13

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

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

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

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

于 2015-06-23T08:35:36.223 に答える