最初のEF4.3コード(ただし、EFによって生成されたデータベースとは対照的に、明示的に設計されたデータベースを使用)では、次の問題が発生します。
1対多の「Break」エンティティを含むことができるエンティティ「WorkPlan」があります。モデルでは、作業計画にはICollectionがありますが、Breakは作業計画について認識していません。
これは集約的な関係です。「ブレーク」は、作業計画の範囲外に存在することはできません。
私がしたいのは、WorkPlanのブレークのコレクションからブレークを削除するときに、変更を保存するときにそのブレークをデータベースから削除する必要があるということです。
[Test]
public void ShouldRemoveBreakInDatabase()
{
// Setup
var workPlan = WorkPlanBuilder.Build(x => x.AddBreak());
Save(workPlan);
// Exercise
var exerciseContext = CreateDataContext();
workPlan = exerciseContext.WorkPlans.Single();
workPlan.RemoveBreak(workPlan.Breaks.Single());
exerciseContext.SaveChanges();
// Verify
var actual = SqlHelper.ExecuteScalar("select count(*) from Breaks");
Assert.That(actual, Is.EqualTo(0));
}
ただし、SaveChanges()呼び出しでは、次の例外が発生します。
System.Data.Entity.Infrastructure.DbUpdateException:関係の外部キープロパティを公開していないエンティティの保存中にエラーが発生しました。単一のエンティティを例外のソースとして識別できないため、EntityEntriesプロパティはnullを返します。保存中の例外の処理は、エンティティタイプの外部キープロパティを公開することで簡単にできます。詳細については、InnerExceptionを参照してください。
----> System.Data.UpdateException:エントリの更新中にエラーが発生しました。詳細については、内部例外を参照してください。
----> System.Data.SqlClient.SqlException:値NULLを列'WorkPlan_Id'、テーブル'ActivityStore.dbo.Breaks'に挿入できません。列はnullを許可しません。UPDATEは失敗します。ステートメントは終了されました。
WorkPlanのコレクションからBreakを削除するとき、EFはデータベースでWorkPlan_Idフィールドをnullに設定する必要があると想定しますが、フィールドはnull可能ではないことは明らかです。
データコンテキストに以下を追加します。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<WorkPlan>().HasMany(x => x.Breaks).WithRequired();
}
別の例外が発生します:
System.Data.Entity.Infrastructure.DbUpdateException:関係の外部キープロパティを公開していないエンティティの保存中にエラーが発生しました。単一のエンティティを例外のソースとして識別できないため、EntityEntriesプロパティはnullを返します。保存中の例外の処理は、エンティティタイプの外部キープロパティを公開することで簡単にできます。詳細については、InnerExceptionを参照してください。
----> System.Data.UpdateException:「WorkPlan_Breaks」AssociationSetからの関係は「削除済み」状態です。多重度の制約がある場合、対応する「WorkPlan_Breaks_Target」も「Deleted」状態である必要があります。
これを機能させる簡単な方法はありますか?