C# 在web api中部分更新实体框架核心中的复杂对象

C# 在web api中部分更新实体框架核心中的复杂对象,c#,entity-framework-core,asp.net-core-webapi,C#,Entity Framework Core,Asp.net Core Webapi,我在尝试更新ASP.NET核心Web API中相当复杂的对象时遇到问题 我将put方法更改为以下代码: [Authorize(Policy = "IsAuthor")] [HttpPut("{id}")] public async Task<IActionResult> PutCIApplication([FromRoute] Guid id, [FromBody] CIApplication cIApplication) { if (

我在尝试更新ASP.NET核心Web API中相当复杂的对象时遇到问题

我将put方法更改为以下代码:

    [Authorize(Policy = "IsAuthor")]
    [HttpPut("{id}")]
    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();

        cIApplication.Translations[userLang].Name = cIApplication.Name;
        cIApplication.Translations[userLang].Description = cIApplication.Description;

        var dbCIApplication = await _context.CIApplications.Include(c => c.Translations)
                        .Include(c => c.DeploymentScenarios).ThenInclude(d => d.InstallSequence).ThenInclude(s => s.Steps).ThenInclude(s => s.SubSteps)
                        .Include(c => c.DeploymentScenarios).ThenInclude(d => d.UninstallSequence).ThenInclude(s => s.Steps).ThenInclude(s => s.SubSteps)
                        .Include(c => c.SoftwareMeteringRules).Include(c => c.Catalogs).Include(c => c.Categories)
                        .AsNoTracking()
                        .SingleOrDefaultAsync(m => m.ID == id);

        HashSet<string> excludedProperties = new HashSet<string>();
        excludedProperties.Add("OwnerCompanyID");
        excludedProperties.Add("OwnerCompany");
        excludedProperties.Add("CreatedDate");
        excludedProperties.Add("CreatedBy");
        excludedProperties.Add("UpdatedDate");
        excludedProperties.Add("UpdatedBy");

        var patch = JsonPatchCreation.CreatePatch(dbCIApplication, cIApplication, excludedProperties);

        if ((await _authorizationService.AuthorizeAsync(User, cIApplication, "CIAuthoringManagement")).Succeeded)
        {
            patch.ApplyTo(dbCIApplication);

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

            return NoContent();
        }
        else
        {
            return Unauthorized();
        }
 }
[授权(Policy=“IsAuthor”)]
[HttpPut(“{id}”)]
公共异步任务应用程序([FromRoute]Guid id,[FromBody]应用程序应用程序)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
if(id!=cIApplication.id)
{
返回请求();
}
字符串userLang=HttpContext.Request.Headers[“UserCulture”].ToString();
cIApplication.Translations[userLang].Name=cIApplication.Name;
cIApplication.Translations[userLang].Description=cIApplication.Description;
var dbCIApplication=await_context.CIApplications.Include(c=>c.Translations)
.Include(c=>c.DeploymentScenarios)。然后Include(d=>d.InstallSequence)。然后Include(s=>s.Steps)。然后Include(s=>s.SubSteps)
.Include(c=>c.DeploymentScenarios)。然后Include(d=>d.UninstallSequence)。然后Include(s=>s.Steps)。然后Include(s=>s.SubSteps)
.Include(c=>c.SoftwareMeteringRules)。Include(c=>c.Catalogs)。Include(c=>c.Categories)
.AsNoTracking()
.SingleOrDefaultAsync(m=>m.ID==ID);
HashSet excludedProperties=新HashSet();
不包括不动产。添加(“所有者公司ID”);
不包括不动产。添加(“所有者公司”);
excludedProperties.Add(“CreatedDate”);
excludedProperties.Add(“CreatedBy”);
不包括不动产。添加(“更新日期”);
excludedProperties.Add(“更新人”);
var patch=JsonPatchCreation.CreatePatch(dbcApplication、cApplication、excludedProperties);
if((wait _authorizationService.authorizationAsync(用户、cIApplication、“CIAuthoringManagement”)).成功)
{
patch.ApplyTo(dbCIApplication);
尝试
{
wait_context.SaveChangesAsync();
}
catch(DbUpdateConcurrencyException)
{
如果(!cApplicationExists(id))
{
返回NotFound();
}
其他的
{
投掷;
}
}
捕获(例外)
{
投掷;
}
返回NoContent();
}
其他的
{
未经授权返回();
}
}
正如您所看到的,
CIApplication
类包含许多与其他类的关系,并且依赖类本身也有很多关系

此控制器操作适用于没有任何关系的简单对象

但在这种情况下,控制器不会抛出任何异常,但对象不会在数据库中更新

我第一次尝试不使用
.AsNoTracking
,但在本例中,我有一个异常,即
部署场景已被跟踪

我想进行部分更新,因为某些关系不是通过get操作发送到我的本地客户端的(在本例中为
OwnerCompany
),因此当发送对象进行更新时,导航属性具有空值,因此EF Core会删除该关系

如果有人对如何使它以最简单的方式工作有想法,那就太好了


谢谢

首先,我将它放在一个try/catch块中,为它编写一个单元测试,然后慢慢地构建它,这将帮助您确定它不喜欢哪些包含。同样作为一项规则,所有这些都不应该在控制器中。有些应该推回到服务层,而上下文保存更改应该直接返回到存储库层。