Entity Framework Core 2 : Easily update an object and it's relations

automapper entity-framework-core put

Question

In an asp net core + ef core 2.0 web api project I'm using a put method defined as below in which I have to update each properties of my entities one by one :

public async Task<IActionResult> PutCIApplication([FromRoute] Guid id, [FromBody] CIApplication cIApplication)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != cIApplication.ID)
        {
            return BadRequest();
        }

        string userLang = HttpContext.Request.Headers["UserCulture"].ToString();
        var dbCIApplication = await _context.CIApplications.Include(c => c.Translations).Include(c => c.DeploymentScenarios).SingleOrDefaultAsync(m => m.ID == id);

        if (dbCIApplication == null)
        {
            return NotFound();
        }

        //Name and Desc are localized properties, they are stored in a collection of Translation with one to many relationship
        dbCIApplication.Translations[userLang].Name = cIApplication.Name;
        dbCIApplication.Translations[userLang].Description = cIApplication.Description;
        dbCIApplication.UpdatedBy = cIApplication.UpdatedBy;
        dbCIApplication.Status = cIApplication.Status;
        dbCIApplication.Publisher = cIApplication.Publisher;
        // And the list goes on...
        //... and on...

        _context.CIApplications.Update(dbCIApplication);

        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!CIApplicationExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return NoContent();
    }

It works very well, so I don't really have an issue but I was wondering if there a way to avoid the part where I copy each properties one by one.

I tried with automapper but as it creates a new instance I get a "cannot be tracked because another instance of this type with the same key is already being tracked" error.

I would have liked to use some reusable code in which I could pass my object to update and a list of proprties to ignore. But I'm not enough a good coder to set it up, if someone had a great idea it would be awesome !

Thanks !

1
3
10/20/2017 8:11:35 AM

Accepted Answer

This is the point where you should probably start rethinking your design but nevertheless you can in fact us AutoMapper and turn off tracking.

Check out this link: https://docs.microsoft.com/en-us/ef/core/querying/tracking

var dbCIApplication = await _context
                .CIApplications
                .AsNoTracking()
                .Include(c => c.Translations)
                .Include(c => c.DeploymentScenarios)
                .SingleOrDefaultAsync(m => m.ID == id);
0
10/20/2017 5:32:32 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow