问题
I try to implement Unit of Work pattern in my application with use of nested units of work.
I have the following interfaces:
interface IDataService
{
IUnitOfWork NewUnitOfWork();
INestedUnitOfWork NewNestedUnitOfWork(IUnitOfWork parent);
}
interface IUnitOfWork : IDisposable
{
void Commit();
}
interface INestedUnitOfWork : IUnitOfWork
{
IUnitOfWork Parent { get; }
object GetParentObject(object obj); // get the same object in parent uow
object GetNestedObject(object obj); // get the same object in this uow
}
This is almost how things happen in XPO.
Is there any chance to implement these interfaces using Entity Framework, suppose version 4, with little pain?
I use auto-generated entity objects, not POCO.
回答1:
Not exactly your way, because I'm using POCO with state flags, but it can be applied to generated entities as well. This is a recursive approach to manage the state of the parent entity and children entities. This is the state manager class for the Parent
entity:
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);
}
}
}
And this is the state manager for the Child
entity:
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
is a simple interface which only has ChangeState
method.
If the Child
entity had a GrandChild
collection, the ChildStateManager.SetRelationsState()
method would call the GrandChildStateManager.ChangeState()
and so on. It's a bit complicated, but it works for me and I generate the state manager code using T4 templates.
来源:https://stackoverflow.com/questions/10672744/nested-unit-of-work-in-entity-framework