Question

I've been tasked with the glorious mission of modernizing a CRUD system (Ironic). I'm using EF 6.1.1 and WebApi. I send the Entity using a DTO (dynamic object for now will create a static type when all is working, will also make the calls async)

[HttpGet]
public dynamic Get(int id)
{
    var p = personRepository.Get(id);

    return new
    {
        p.PersonId,
        p.BirthYear,
        p.DeathYear,
        p.Comment,
        PersonNames = p.PersonNames.Select(pn => new { pn.PersonId, pn.PersonNameId, pn.NameTypeId, pn.Firstname, pn.Prefix, pn.Surname })
    };
}

I then update fields on the Person object or add/remove/update PersonNames collection using Knockout and ko.mapping

I post the result to this WebApi method

[HttpPost]
public void Post([FromBody]Person person)
{
    personRepository.Merge(person);
}

All the id's etc are correct, in personRepository.Merge i've tried

public void Merge(Person person)
{
    db.People.AddOrUpdate(person);
    db.SaveChanges();
} 

This works for the fields directly on the personobject, but it does not work with add/remove/update on the PersonNames

Can I support this without writing manual merge code?

Solution Ended up doing this

public void Merge(Person person)
{
    db.People.AddOrUpdate(person);
    var existingNames = db.PersonNames.Where(pn => pn.PersonId == person.PersonId).ToList();
    var deleted = existingNames.Where(pn => person.PersonNames.All(d => d.PersonNameId != pn.PersonNameId));
    db.PersonNames.RemoveRange(deleted);

    foreach (var name in person.PersonNames)
    {
        db.PersonNames.AddOrUpdate(name);
    }
    db.SaveChanges();
}
Was it helpful?

Solution

Given you've mentioned this is a CRUD system this all looks sensible to me. I can't see how you can really avoid mapping from your DTO's back to your domain entities (e.g. Person)

I expect you've thought of it already, but how about removing as much boiler plate merge code as possible using something like AutoMapper? https://github.com/AutoMapper/AutoMapper

Mapping does get complicated for navigational properties (i.e. mapping between an object graph of DTO's back to an object graph of entities). This link goes into far more detail than I can: http://rogeralsing.com/2013/12/01/why-mapping-dtos-to-entities-using-automapper-and-entityframework-is-horrible/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top