EF Core получает древовидную иерархию до последнего потомка - PullRequest
0 голосов
/ 23 марта 2020

Я использую EF Core 3.1 с SQL Сервером, и у меня есть приложение с вопросами. Каждый вопрос может иметь один или несколько вариантов. Это может распространяться на неограниченные уровни. например,

What is your Country?
|
|--France
|--United Kingdom
|--United States
   |---What is your state?
       |---New York
       |---Alaska
       |---California
           |---What is your City?
               |--- Los Angeles
               |--- San Diego
               |--- San Francisco       

Я хочу получить полный путь к вопросу.

Мой код следующий:

public class MyDbContext : DbContext
{
    public MyDbContext(DbContextOptions options)
        : base(options)
    {
        Database.Migrate();
    }

    public virtual DbSet<Question> Question { get; set; }
    public virtual DbSet<Option> Option { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Question>(entity =>
        {
            entity.HasMany(x => x.Options)
                .WithOne(x => x.ParentQuestion)
                .IsRequired();
        });

        modelBuilder.Entity<Option>(entity =>
        {
            entity.HasMany(x => x.SubQuestions)
                .WithOne(x => x.ParentOption);
        });
    }

    public class Question
    {
        public Question()
        {
            Options = new HashSet<Option>();
        }

        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public long Id { get; set; }

        public string QuestionText { get; set; }

        // A Question may have one or more than one options
        public virtual ICollection<Option> Options { get; set; }

        // An Option may have one or more Questions 
        public long? ParentOptionId { get; set; }
        public virtual Option ParentOption { get; set; }
    }

    public class Option
    {
        public Option()
        {
            SubQuestions = new HashSet<Question>();
        }

        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public long Id { get; set; }

        public string OptionText { get; set; }

        // A Question may have one or more than one options
        public long ParentQuestionid { get; set; }
        public virtual Question ParentQuestion { get; set; }

        // An Option may have one or more Questions 
        public virtual ICollection<Question> SubQuestions { get; set; }
    }
}

Я выполняю:

var questionTree = (from question in context.Question
                                            .Include(x => x.Options)
                                            .ThenInclude(x => x.SubQuestions)
                    select question).FirstOrDefault();

Но он возвращает только первый уровень. Как я могу получить все дерево до самого низкого уровня?

И как только эта база данных накапливает сотни тысяч вопросов, это повлияет на производительность?

...