Entity Frameworkでの削除に問題があります。つまり、EFはデータベースでカスケード削除を使用するように明示的に構成したにもかかわらず、明示的にデータベースからエンティティを削除しようとします。
私のデザイン:
エンティティタイプには、MainEntity
、EntityTypeA
、EntityTypeB
の3つがあります。 EFは、EntityTypeA
およびEntityTypeB
を削除するときにカスケード削除を使用するように構成されています。つまり、MainEntity
のインスタンスを削除すると、関連するすべてのEntityTypeA
およびEntityTypeB
インスタンスも削除されます。私はEntityTypeA
またはEntityTypeB
を削除せず、親も削除しません。
私の問題は、EFがDELETE
に対してEntityTypeA
ステートメントを明示的に発行することです。これにより、アプリケーションがクラッシュします。
これは私のモデルのようになります:
関係には、次のデフォルト以外の設定があります。
MainEntity -> EntityTypeA OnDelete: Cascade
MainEntity -> EntityTypeB OnDelete: Cascade
関係EntityTypeA -> EntityTypeB
にはOnDelete: None
データベースの内容
INSERT INTO MainEntities (Name) values ('Test')
insert into EntityTypeA (MainEntityID) VALUES (1)
insert into EntityTypeB (MainEntityID, EntityTypeAId) VALUES (1, 1)
insert into EntityTypeB (MainEntityID, EntityTypeAId) VALUES (1, 1)
マイコード:
class Program
{
static void Main(string[] args)
{
var context = new Model1Container();
var mainEntity = context.MainEntities.Include("EntityTypeA").SingleOrDefault();
context.DeleteObject(mainEntity);
context.SaveChanges();
}
}
どうなる
SaveChangesを呼び出すと、Entity Frameworkはデータベースで以下を実行します。
exec sp_executesql N'delete [dbo].[EntityTypeA]
where ([Id] = @0)',N'@0 int',@0=1
EntityTypeAインスタンスを参照するEntityTypeBのテーブルに項目があるため、これにより外部キー違反が発生します。
質問
カスケード削除を使用するようにEntity Frameworkを構成したにもかかわらず、Entity FrameworkがEntityTypeAのインスタンスに対して明示的な削除を発行するのはなぜですか? Include( "EntityTypeA")を削除すると、再び機能し始めます。
これは、EFでカスケード削除が動作する方法とまったく同じです。 EFデザイナーのリレーションにCascadeを設定すると、読み込まれた実現エンティティごとにDELETE
ステートメントを実行するようにEFに指示されます。 ON CASCADE DELETE
データベース内。
EFの使用時にカスケード削除を設定するには、2つの手順が必要です。
ON CASCADE DELETE
データベースのリレーション。これは、親の削除時にコンテキストにロードされなかったであるすべての関連レコードを削除するようにSQLに指示します。EFでのカスケード削除の実装は奇妙で非常に非効率的ですが、これはその動作であり、使用する場合は、このシナリオでアプリケーションが正しく動作するように変更する必要があります。
EFデザイナーではなく、データベースのFK制約にカスケード削除を設定することもできます。
カスケード削除を設定する方法について、Sql Server Management Studio(SSMS)の視覚的な手順を次に示します。
完了したら、削除する前に、データベースに対してedmxを更新するを忘れないでください。
これについてはブログで詳しく説明します。 Entity Framework Cascading Deletes; Set it from the database。