次の2つの方法を使用してEFを使用してデータベースから項目を削除できます。
1つ目はEntityCollection
、2つ目はObjectContext
です。
それぞれをいつ使うべきですか?
一方が他方よりも好まれていますか?
Remove()
はbool
を返し、DeleteObject()
はvoid
を返します。
両方の方法で "アイテムをデータベースから削除する"ことができるのは、一般的に正しくありません。正確に言うと、
ObjectContext.DeleteObject(entity)
は、コンテキスト内でエンティティをDeleted
name __としてマークします。 (EntityState
name__はその後のDeleted
name__です。)その後にSaveChanges
name__を呼び出すと、EFはSQLのDELETE
name__ステートメントをデータベースに送信します。データベース内の参照制約に違反していない場合は、エンティティは削除されます。それ以外の場合は、例外がスローされます。
EntityCollection.Remove(childEntity)
は、parentとchildEntity
name__の関係をDeleted
name __としてマークします。 childEntity
name__自体がデータベースから削除され、SaveChanges
name__を呼び出したときに実際に何が起こるかは、2つの間の関係の種類によって異なります。
関係がoptionalの場合、つまりデータベース内の子から親への外部キーでNULL
name__値を使用できる場合、この外部キーはnullに設定されます。 SaveChanges
name__に対するNULL
name__のこのchildEntity
name__値は、データベースに書き込まれます(つまり、2つの関係は削除されます)。これはSQLのUPDATE
name__ステートメントで起こります。 DELETE
name__ステートメントは発生しません。
関係がrequired(FKがNULL
name__値を許可しない)で、関係がnot識別(の場合)つまり、外部キーは子の(複合)主キーの一部ではありません)子を別の親に追加するか、子を明示的に削除する必要があります(DeleteObject
thenを使用)。これらを行わないと、参照制約に違反し、SaveChanges
name__を呼び出したときにEFが例外をスローします - 悪名高い " 関係が変更されなかったのは、外部キーのプロパティはnullを許容しない "例外など。
関係が識別の場合(必然的にrequiredの場合、主キーのどの部分もNULL
name__にすることはできないため)EF childEntity
name__をDeleted
name__としてもマークします。 SaveChanges
name__を呼び出すと、SQLのDELETE
name__ステートメントがデータベースに送信されます。データベース内の他の参照制約に違反していなければ、そのエンティティは削除されます。そうでなければ、例外がスローされます。
私は実際には少し混乱しています MSDNページのRemarksセクション リンクしています: "リレーションシップに参照整合性制約がある場合は、Removeメソッドを呼び出します。依存オブジェクトは関係と依存オブジェクトの両方を削除対象としてマーク付けします "#:。上記の3つのケースはすべて "参照整合性制約"を持っていますが、実際には子が実際に削除される場合に限り、これは不正確であるかさらには間違っているようです。 ( "従属オブジェクト"で識別されている関係に参加しているオブジェクトを意味しているのであれば、それは珍しい用語ですが)
本当にDeletedを使いたいのであれば、あなたはあなたの外部キーをnullにすることができるようにしなければならないでしょう、しかし、あなたは孤立したレコードになってしまいます。 Remove()
を使うだけです
ObjectContext.DeleteObject(entity) は、コンテキスト内でエンティティを削除済みとしてマークします。 (その後、EntityStateは削除されます。)後でSaveChangesを呼び出すと、EFはSQL DELETEステートメントをデータベースに送信します。データベース内の参照制約に違反していない場合は、エンティティは削除されます。それ以外の場合は、例外がスローされます。
EntityCollection.Remove(childEntity) は、parentとchildEntityの関係を削除済みとしてマークします。 childEntity自体がデータベースから削除され、SaveChangesを呼び出したときに実際に何が起こるかは、2つの間の関係の種類によって異なります。
注目に値するのは、.State = EntityState.Deleted
を設定しても自動的に検出された変更が行われないことです。( archive )