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);
在一个 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);