簡體   English   中英

.NET 核心實體框架 - 只添加新的子實體

[英].NET Core Entity Framework - Only add new child entities

我在更新具有數據庫中已存在的子實體的父實體時遇到一些問題。

我有一個與 Answer 實體具有多對多關系的 Question 實體。 簡化版本如下所示:

public class Question
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
    
    [JsonIgnore]
    public virtual List<QuestionParentRelation>? ParentQuestions { get; set; }
    [JsonIgnore]
    public virtual List<QuestionParentRelation>? ChildQuestions { get; set; }
    
    public string Name { get; set; }
    
    public virtual List<Answer>? PossibleAnswers { get; set; }
}

public class Answer
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
    
    public string AnswerText { get; set; }
    
    [JsonIgnore]
    public List<Question> Questions { get; set; }
}

但是與其他問題也存在多對多關系,因為在 UI 端有一個拖放允許創建子后續問題等。這種關系包含一個ParentQuestionAnswerId (一個外鍵,表示在顯示子問題之前,應該對父問題給出哪個答案)。

public class QuestionParentRelation
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid RelationId { get; set; }

    public Guid? ParentId { get; set; }
    public Guid ChildId { get; set; }
    
    public virtual Question ParentQuestion { get; set; }
    public virtual Question ChildQuestion { get; set; }
    
    public int ParentHashNum { get; set; }
    public int ChildHashNum { get; set; }
    
    // FK: The answer that is needed before the child question is shown
    public Guid? ParentQuestionAnswerId { get; set; }
    [JsonIgnore]
    public virtual Answer? ParentQuestionAnswer { get; set; }

    public int Level { get; set; }
    public int Order { get; set; }
}

現在的問題是,每次我嘗試更新問題實體時(使用給定的現有答案實體列表):

  1. 我收到一條錯誤消息,指出該特定答案 ID 存在重復條目
  2. 如果我首先嘗試從數據庫中刪除答案,則會收到一條錯誤消息,指出存在失敗的外鍵約束 (ParentQuestionAnswerId)。 (但如果首先刪除 Answer 實體是唯一的解決方案我不希望所有 QuestionParentRelation 實體將 ParentQuestionAnswerId 設置為 NULL ,因為這也會影響不應編輯的關系)

這是我在 FluentAPI 中配置的:

builder.Entity<Question>()
    .HasMany(q => q.PossibleAnswers)
    .WithMany(a => a.Questions)
    .UsingEntity(join => join.ToTable("QuestionPossibleAnswers"));

builder.Entity<QuestionParentRelation>()
    .ToTable("QuestionParentRelations")
    .HasKey(r => new { r.RelationId });

builder.Entity<Question>()
    .HasMany(q => q.ParentQuestions)
    .WithOne(r => r.ChildQuestion)
    .HasForeignKey(r => r.ChildId);

builder.Entity<Question>()
    .HasMany(q => q.ChildQuestions)
    .WithOne(r => r.ParentQuestion)
    .HasForeignKey(r => r.ParentId);

好吧,對於任何偶然發現這個問題的人來說:我仍然不知道 EF 是否有辦法自己處理這個問題,但我通過循環問題 DTO object 中的答案然后比較它們來解決它與實體。

如果實體中已經存在答案,我只需將其從 DTO 中刪除並將更新后的 DTO 發送到服務。 這樣,現有答案就不會被添加兩次。

QuestionsController 的 HttpPut 方法內部

var question = _questionService.EagerGetBy(q => q.Id == Guid.Parse(id));
if (question is null)
    return NotFound("Geen resultaat gevonden voor Id " + id);

if (questionDto.PossibleAnswers != null && question.PossibleAnswers != null)
{
    questionDto.PossibleAnswers.ForEach(a =>
    {
        if (a.Id != null && question.PossibleAnswers.Contains(a))
            questionDto.PossibleAnswers.Remove(a);
    });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM