实体框架核心2:轻松更新对象及其关系

时间:2017-10-20 08:11:36

标签: automapper entity-framework-core put

在asp net core + ef core 2.0 web api项目中,我使用下面定义的put方法,我必须逐个更新我的实体的每个属性:

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();
    }

它运作得很好,所以我真的没有问题,但我想知道是否有办法避免我逐个复制每个属性的部分。

我尝试使用automapper,但是当它创建一个新实例时,我得到一个&#34;无法跟踪,因为已经跟踪了具有相同密钥的此类型的另一个实例&#34;错误。

我本来希望使用一些可重用的代码,我可以在其中传递我的对象进行更新,以及要忽略的属性列表。但是,如果有人有一个好主意,那我就不是一个好的编码器,那就太棒了!

谢谢!

1 个答案:

答案 0 :(得分:0)

这一点你可能应该开始重新思考你的设计,但实际上我们可以使用AutoMapper并关闭跟踪。

查看此链接: 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);