如何在实体框架核心中映射一对多可选递归关系

Tox*_*xic 1 c# entity-framework-core .net-core-2.0

我有实体调用答案和答案实体可以有多个子答案,即集合我正在努力将它映射到我的模型配置类中。

模型类

public class AnswerDataModel : IDataModel<Guid>
{
    public AnswerDataModel()
    {

        SubQuestionAnswers = new HashSet<AnswerDataModel>();
    }
    public Guid Id { get; set; }

    public Guid QuestionId { get; set; }

    public string Value { get; set; }

    public virtual ICollection<AnswerDataModel> SubQuestionAnswers { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

答案配置类

public class AnswerEntityConfiguration : IEntityTypeConfiguration<AnswerDataModel>
{
    public void Configure(EntityTypeBuilder<AnswerDataModel> builder)
    {
        builder.ToTable("Answers");
        builder.HasKey(answer => answer.Id);

        builder
            .HasOne(answer => answer.Question)
            .WithMany(question => question.Answers)
            .HasForeignKey(answer => answer.QuestionId);

       builder
             .????????  // how to map recursive Answer Collections as subQuestionAnswer??

    }
}
Run Code Online (Sandbox Code Playgroud)

Iva*_*oev 9

您从集合导航属性开始:

builder
    .HasMany(answer => answer.SubQuestionAnswers)
Run Code Online (Sandbox Code Playgroud)

其余的取决于模型中是否存在反向导航属性和显式 FK 属性。

(A) 原始模型(无反向导航属性,无显式 FK 属性)

.WithOne()
.HasForeignKey("ParentId")
.IsRequired(false);
Run Code Online (Sandbox Code Playgroud)

(B) 将反向导航属性添加到模型中

public virtual AnswerDataModel Parent { get; set; }
Run Code Online (Sandbox Code Playgroud)

这将是:

.WithOne(answer => answer.Parent);
Run Code Online (Sandbox Code Playgroud)

(C) 将显式 FK 属性添加到模型中

public Guid? ParentId { get; set; }
Run Code Online (Sandbox Code Playgroud)

这将是:

.WithOne()
.HasForeignKey(answer => answer.ParentId);
Run Code Online (Sandbox Code Playgroud)

(D) 将反向导航和显式 FK 属性添加到模型中

public virtual AnswerDataModel Parent { get; set; }
public Guid? ParentId { get; set; }
Run Code Online (Sandbox Code Playgroud)

这将是:

.WithOne(answer => answer.Parent)
.HasForeignKey(answer => answer.ParentId);
Run Code Online (Sandbox Code Playgroud)

HasForeignKey这里可以跳过,因为这是惯例)