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 !
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://learn.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);