C# 在web api中部分更新实体框架核心中的复杂对象
我在尝试更新ASP.NET核心Web API中相当复杂的对象时遇到问题 我将put方法更改为以下代码: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 (
[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块中,为它编写一个单元测试,然后慢慢地构建它,这将帮助您确定它不喜欢哪些包含。同样作为一项规则,所有这些都不应该在控制器中。有些应该推回到服务层,而上下文保存更改应该直接返回到存储库层。