I’m trying out Entity Framework Code first CTP4. Suppose I have:
public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Child
{
public int Id { get; set; }
public string Name { get; set; }
public Parent Mother { get; set; }
}
public class TestContext : DbContext
{
public DbSet<Parent> Parents { get; set; }
public DbSet<Child> Children { get; set; }
}
public class ChildEdit
{
public int Id { get; set; }
public string Name { get; set; }
public int MotherId { get; set; }
}
Mapper.CreateMap<Child, ChildEdit>();
Mapping to the Edit model is not a problem. On my screen I select the mother through some control (dropdownlist, autocompleter, etc) and the Id of the mother gets posted in back:
[HttpPost]
public ActionResult Edit(ChildEdit posted)
{
var repo = new TestContext();
var mapped = Mapper.Map<ChildEdit, Child>(posted); // <------- ???????
}
How should I solve the last mapping? I don’t want to put Mother_Id in the Child object. For now I use this solution, but I hope it can be solved in Automapper.
Mapper.CreateMap<ChildEdit, Child>()
.ForMember(i => i.Mother, opt => opt.Ignore());
var mapped = Mapper.Map<ChildEdit, Child>(posted);
mapped.Mother = repo.Parents.Find(posted.MotherId);
EDIT
This works, but now I have to do that for each foreign key (BTW: context would be injected in final solution):
Mapper.CreateMap<ChildEdit, Child>();
.ForMember(i => i.Mother,
opt => opt.MapFrom(o =>
new TestContext().Parents.Find(o.MotherId)
)
);
What I’d really like would be:
Mapper.CreateMap<int, Parent>()
.ForMember(i => i,
opt => opt.MapFrom(o => new TestContext().Parents.Find(o))
);
Mapper.CreateMap<ChildEdit, Child>();
Is that possible with Automapper?
First, I’ll assume that you have a repository interface like
IRepository<T>Afterwards create the following class:
Basically this class will be used to do all the conversion between an int and a domain entity. It uses the “Id” of the entity to load it from the Repository. The IRepository will be injected into the converter using an IoC container, but more and that later.
Let’s configure the AutoMapper mapping using:
I suggest creating this “generic” mapping instead so that if you have other references to “Mother” on other classes they’re mapped automatically without extra-effort.
Regarding the Dependency Injection for the IRepository, if you’re using Castle Windsor, the AutoMapper configuration should also have:
I’ve used this approach and it works quite well.