在Entity Framework核心中执行LINQ以加载子相关实体Data

时间:2018-02-11 18:36:22

标签: linq .net-core entity-framework-core

我正在使用Entity Framework Core开发.NET Core应用程序。我有三个表问题,答案和答案类型 架构是

question <-- 1:* --> Answers <-- 1:1--> AnswerTypes

我需要运行使用ICollection of Answer返回问题的查询,进一步使用AnswerType回答

问题

public class QuestionDataModel
{
    public QuestionDataModel()
    {
        Answers = new HashSet<AnswerDataModel>();
    }

    public Guid Id { get; set; }
    public virtual ICollection<AnswerDataModel> Answers { get; set; }

}

答案

public class AnswerDataModel
{
    public AnswerDataModel()
    {
    }

    public Guid Id { get; set; }
    public Guid QuestionId { get; set; }
    public virtual QuestionDataModel Question { get; set; }
    public string Value { get; set; }
    public Guid AnswerStatusTypeId { get; set; }
    public virtual AnswerStatusTypeDataModel AnswerStatusType { get; set; }

}

AnswerStatusType

public class AnswerStatusTypeDataModel
{
    public AnswerStatusTypeDataModel()
    {
        Answers = new HashSet<AnswerDataModel>();
    }

    public Guid Id { get; set; }

    public string Name { get; set; }

    public virtual ICollection<AnswerDataModel> Answers { get; set; }
}

我已经尝试过嵌套连接来获取集合中每个答案的AnswerStatusType但是收到错误“声明了无效的匿名类型成员,必须使用成员分配,简单名称或成员访问来声明匿名类型成员”。此错误出现在以下代码中的第二个嵌套连接中,

LINQ

 var query3 = Context.Questions.Join(Context.Answers,
                       question => question.Id,
                       answer => answer.QuestionId,
                       (question, answer) => new
                       {
                           question.Id,
                           question.Title,
                           question.Answers.Join(Context.AnswerStatusTypes,
                                                  answer => answer.AnswerStatusTypeId,
                                                  answerStatus => answerStatus.Id,
                                                  (answers, answerStatus) => new
                                                  {
                                                      answerStatus
                                                  })
                       }
                     );

配置类

 and configuration classes as

问题配置

  public void Configure(EntityTypeBuilder<QuestionDataModel> builder)
    {

        builder.ToTable("Questions");
        builder.HasKey(question => question.Id);
        builder.HasMany(question => question.Answers);
    }

回答配置

     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
            .HasOne(answer => answer.AnswerStatusType)
            .WithMany(answerType => answerType.Answers)
            .HasForeignKey(answer => answer.AnswerStatusTypeId);
    }

AnswerStatus COnfig

    public void Configure(EntityTypeBuilder<AnswerStatusTypeDataModel> builder)
    {
        builder.ToTable("AnswerStatusTypes");
        builder.HasKey(answerStatusType => answerStatusType.Id);
        builder.HasMany(answerStatusType => answerStatusType.Answers);
    }

2 个答案:

答案 0 :(得分:2)

您的实体配置对我来说是正确的。

@Ivan Stoev指出,

var questions = context.Questions
    .Include(x => x.Answers)
        .ThenInclude(x => x.AnswerStatusType)
    // Now since we have the AnswerStatusType loaded we can do something like this as well.
    //.Where(x => x.Answers.Conatins(a => a.AnswerStatusType.Name == "Some Status Name"))
    .ToList();

这应该做!

答案 1 :(得分:0)

var result = Context.Questions
             .Include(x=>x.Answers.Select(y=>y.AnswerType))
             .Where(x=>x.ID == QuestionidYouAreLookingFor)
             .ToList();

确保包含System.Data.Entity命名空间

当你调用ToList()时,它实际上将进行SQL调用并执行查询。如果你想延迟加载,那么不要调用ToList()