Entity Framework核心2:轻松更新对象及其关系

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

在一个 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,但当它创建一个新实例时,我收到 "cannot be tracked because another instance of this type with the same key is already being tracked" 错误。

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

谢谢!

此时您可能应该开始重新考虑您的设计,但实际上您可以使用 AutoMapper 并关闭跟踪。

看看这个 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);