私は状態フラグで POCO を使用しているため、正確にはそうではありませんが、生成されたエンティティにも適用できます。これは、親エンティティと子エンティティの状態を管理するための再帰的なアプローチです。Parent
これは、エンティティの状態マネージャー クラスです。
public partial class ParentStateManager : IStateManager<Parent, MyObjContext>
{
private IStateManager<Child, MyObjContext> _ChildStateManager = new ChildStateManager();
public void ChangeState(Parent m, MyObjContext ctx)
{
if (m == null) return;
ctx.Parents.Attach(m);
if (m.IsDeleted)
{
ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Deleted);
}
else
{
if (m.IsNew)
{
ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Added);
}
else
{
if (m.IsDirty)
{
ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Modified);
}
}
}
SetRelationsState(m, ctx);
}
private void SetRelationsState(Parent m, MyObjContext ctx)
{
foreach (Child varChild in m.Children.Where(p => !p.IsDeleted))
{
_ChildStateManager.ChangeState(varChild, ctx);
}
while (m.Children.Where(p => p.IsDeleted).Any())
{
_ChildStateManager.ChangeState(m.Children.Where(p => p.IsDeleted).LastOrDefault(), ctx);
}
}
}
そして、これはChild
エンティティの状態マネージャーです:
public partial class ChildStateManager : IStateManager<Child, MyObjContext>
{
public void ChangeState(Child m, MyObjContext ctx)
{
if (m == null) return;
ctx.Children.Attach(m);
if (m.IsDeleted)
{
ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Deleted);
}
else
{
if (m.IsNew)
{
ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Added);
}
else
{
if (m.IsDirty)
{
ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Modified);
}
}
}
SetRelationsState(m, ctx);
}
private void SetRelationsState(Child m, MyObjContext ctx)
{
}
}
IStateManager
メソッドのみのシンプルなインターフェースChangeState
です。Child
エンティティにGrandChild
コレクションがある場合、ChildStateManager.SetRelationsState()
メソッドは などを呼び出しますGrandChildStateManager.ChangeState()
。少し複雑ですが、うまくいき、T4 テンプレートを使用してステート マネージャー コードを生成します。