1. ホーム
  2. c#

[解決済み] Entity Framework .Remove() と .DeleteObject() の比較

2022-05-12 10:05:56

質問

EFを使用してデータベースから項目を削除するには、次の2つの方法を使用します。

1つ目は EntityCollection で、2つ目は ObjectContext .

それぞれどのような場合に使用するのでしょうか?

どちらを選ぶべきですか?

Remove()boolDeleteObject()void .

どのように解決するのですか?

一般に、" ができることは正しくありません。 データベースから項目を削除する というのは一般に正しくありません。正確にはこのようになります。

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

  • EntityCollection.Remove(childEntity) マーク 親と childEntity として Deleted . もし childEntity を呼び出すと、それ自体はデータベースから削除され、具体的に何が起こるのでしょうか? SaveChanges を呼び出したときに何が起こるかは、2つの関係の種類に依存します。

    • もしその関係が 任意 である場合、すなわち、データベースで子から親を参照する外部キーによって NULL の値がある場合、この外部キーは null に設定され、もし SaveChanges この NULL の値は childEntity の値はデータベースに書き込まれます (つまり、2 つの間の関係が取り除かれます)。この現象は、SQL UPDATE ステートメントで行われます。いいえ DELETE ステートメントが発生します。

    • もしリレーションシップが 必須 (FKでは NULL 値を許しません)、関係は を特定しない (つまり、外部キーが子の (合成) 主キーの一部ではない) 場合は、その子を別の親に追加するか、 明示的にその子を削除しなければなりません (そのためには、( DeleteObject で) 削除しなければなりません。これらのいずれかを行わないと、参照制約に違反することになり、EFは、以下のように呼び出すと例外をスローします。 SaveChanges - 悪名高き " 外部キー プロパティの 1 つまたは複数が NULL 値でないため、リレーションシップを変更できませんでした。 " という例外が発生します。

    • もしリレーションシップが 識別 (それは必ずしも 必須 では主キーのどの部分も NULL にはできないので) EF は childEntity として Deleted も同様です。もしあなたが SaveChanges を呼び出すと、SQL DELETE ステートメントがデータベースに送信されます。データベース内の他の参照制約に違反しない場合はエンティティが削除され、そうでない場合は例外がスローされます。

実はちょっと混乱しているのが MSDN ページにある Remarks セクション と書かれているためです。 リレーションシップに参照整合性制約がある場合、依存オブジェクトで Remove メソッドを呼び出すと、リレーションシップと依存オブジェクトの両方が削除されるようにマークされます。 とあります。上記の 3 つのケースにはすべて " があるため、これは適切でない、あるいは間違っているように思えます。 参照整合性制約 しかし、最後のケースだけは実際に子供が削除されるからです。(彼らが " で意味しない限り; 従属オブジェクト という意味でない限り、識別関係に参加するオブジェクトを意味します(これは珍しい用語でしょう)。