This is probably quite straight forward for some, however I’m a bit confused and can’t find a decent example. Say I’m using view models and my POST action takes in that view model. Typically I would do something along the following lines:
[HttpPost]
public ActionResult Update(UserViewModel uvm)
{
User user = Mapper.Map<UserViewModel, User>(uvm);
_repository.Update(user);
return RedirectToAction("Index");
}
Although this isn’t the full picture. The mapping would work fine, however if I were to just update what I’ve mapped then it’d get rid of valuable data in the database because of course in this case I’m not updating the password or other details.
My repository looks something like this:
public void Update(User user)
{
User u = Session.QueryOver<User>().Where(x => x.UserName == user.UserName).SingleOrDefault();
if (u == null)
throw new Exception("User not found");
u.Forename = user.Forename;
u.Surname = user.Surname;
u.EmailAddress = user.EmailAddress;
}
[I’m using NHibernate so it’ll save the object back to the DB once the session is closed (after the request has finished) automatically for me.]
So my question is, in my repository should I load the “User” entity, then update the values I want, and then save it back, or is there another method to do this? The reason I ask is because it seems a bit… “manual” if you see what I mean? Perhaps it is correct, but I just wanted to see opinions of those with more experience in this area.
Cheers
I use the following approach:
UPDATE:
To address the comments about
AutoMapperhere’s how to proceed:Let’s take for example the following classes:
We don’t want to modify the user password in the UI. So we express our intention to AutoMapper:
and then:
UPDATE 2:
To address the question in the comments about configuring AutoMapper I usually use Profiles:
and then have a registry class which registers all the mappers:
which is called in
Application_Start:Finally my controllers have a reference to the mapping engine:
Now all that’s left is to instruct your DI framework to pass the
Mapper.Engineproperty to the constructor and in your unit tests obviously substitute them with an appropriate mock.