[英]How to remove child entities from parent collection on parent update in Entity Framework Core?
我有以下問題:當我嘗試更新問題並在關鍵字屬性中提供新關鍵字時,該關鍵字尚未與正確添加的問題相關。 假設有兩個關鍵字映射到問題。 然后我用一個與問題無關的關鍵字發送更新請求。 它導致問題被映射到三個關鍵字。 當我發送空的關鍵字列表時,沒有任何變化。 我希望發生的是當我發送一個關鍵字時 - 然后它只是與問題相關的這個關鍵字,其余的被刪除。 我怎樣才能實現以下目標? 我已經嘗試在關鍵字的配置方法中添加“QuestionKeyword”段,但它並沒有太大變化。 另外發生的情況是關鍵字正在從 C# 應用程序內的實體中刪除,但是當我添加一個虛擬代碼行時,再次從上下文中獲取相同的問題,然后在調用 Include() 后再次加載它的問題 - 因為它們從來沒有刪除。
考慮下面的代碼:
public class Keyword
{
public string Name { get; set; }
public List<Question> Questions { get; set; }
}
public class Question : AuditableEntity
{
public int Id { get; set; }
public string Content { get; set; }
public string Answer { get; set; }
public int Rating { get; set; }
public IList<Keyword> Keywords { get; set; } = new List<Keyword>();
}
這些實體按以下方式配置:
public void Configure(EntityTypeBuilder<Keyword> builder)
{
builder.Ignore(entity => entity.DomainEvents);
builder.HasKey(entity => entity.Name);
builder.HasMany(entity => entity.Questions)
.WithMany(entity => entity.Keywords)
.UsingEntity<Dictionary<string, object>>(
"QuestionKeyword",
j => j.HasOne<Question>().WithMany().OnDelete(DeleteBehavior.Cascade),
j => j.HasOne<Keyword>().WithMany().OnDelete(DeleteBehavior.Cascade));
}
public void Configure(EntityTypeBuilder<Question> builder)
{
builder.HasKey(entity => entity.Id);
}
這是更新問題的業務邏輯:
public async Task<Unit> Handle(UpdateQuestionCommand request, CancellationToken cancellationToken)
{
Question question = await _context.Questions.Include(q => q.Keywords).AsNoTracking().SingleOrDefaultAsync(q => q.Id == request.Id, cancellationToken);
if (question == null)
throw new NotFoundException($"Id = {request.Id}");
_context.Keywords.RemoveRange(question.Keywords);
QuestionDto questionDto = _mapper.Map<QuestionDto>(question);
request.PatchDocument.ApplyTo(questionDto);
QuestionDtoValidator validator = new QuestionDtoValidator();
ValidationResult result = validator.Validate(questionDto);
if (!result.IsValid)
{
throw new CustomValidationException(result.Errors);
}
question = _mapper.Map<Question>(questionDto);
_context.Questions.Update(question);
question.DomainEvents.Add(new QuestionUpdatedEvent(question));
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;
}
您必須清除問題的所有關鍵字,然后將新關鍵字添加到您的問題中,如下所示:
Question question = await _context.Questions.Include(q => q.Keywords).SingleOrDefaultAsync(q => q.Id == request.Id, cancellationToken);
question.Keywords.Clear();
....
但請注意AsNoTracking()
已被刪除!
使用AsNoTracking()
意味着獲取的對象更改對您來說無關緊要,EF 將忽略更改!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.