I'm using the "stub technique" to update my POCO's (used in a detached context, ASP.NET MVC).
This is the code i currently have in my controller (which works):
[HttpPost]
public ActionResult Edit(Review review)
{
Review originalReview = _userContentService.FindById(review.PostId) as Review;
var ctx = _unitOfWork as MySqlServerObjectContext;
ctx.ApplyCurrentValues("MyEntities.Posts", review);
_unitOfWork.Commit();
// ..snip - MVC stuff..
}
As you can see, there is code smell everywhere. :)
A few points:
- I use Dependency Injection (interface-based) for basically everything
- I use the Unit of Work pattern to abstract ObjectContext and provide persistence across multiple repositories
- Currently my IUnitOfWork interface has only 1 method:
void Commit();
- Controller have
IUserContentService
andIUnitOfWork
inject by DI IUserContentService
callsFind
in Repositories, which use theObjectContext
.
These are two things i don't like with my above code:
- I don't want to cast the IUnitOfWork as
MySqlServerObjectContext
. - I don't want the Controller to have to care about
ApplyCurrentValues
I basically want my code to look like this:
[HttpPost]
public ActionResult Edit(Review review)
{
_userContentService.Update(review);
_unitOfWork.Commit();
// ..snip - MVC stuff..
}
Any ideas how i can do that? (or something similar).
I already have smarts to work out the entity set name based on the type (combination of generics, pluralization), so don't worry too much about that.
But i'm wondering where the best place to put ApplyCurrentValues
is? It doesn't seem appropriate to put it in the IUnitOfWork
interface, as this is a persistence (EF) concern. For the same reason it doesn't belong in the Service. If i put it in my MySqlServerObjectContext
class (makes sense), where would i call this from, as nothing directly has access to this class - it is injected via DI when something requests IUnitOfWork
.
Any thoughts?
EDIT
I have a solution below using the stub technique, but the problem is if i had retrieved the entity i am updating beforehand, it throws an exception, stating an entity with that key already exists.
Which makes sense, although i'm not sure how can resolve this?
Do i need to "check if the entity is already attached, if not, attach it?"
Can any EF4 experts out there help?
EDIT
Nevermind - found the solution, see answer below.