【问题标题】:Perform LINQ in Entity Framework core to load sub-related entities Data在 Entity Framework core 中执行 LINQ 以加载子相关实体数据
【发布时间】:2018-02-12 09:45:25
【问题描述】:

我正在使用 Entity Framework Core 开发 .NET Core 应用程序。我有三个表 Questions、Answer 和 AnswerType 所以架构是

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

我需要运行查询,返回带有 ICollection 的 Answer 问题,进一步 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);
    }

答案状态配置

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

【问题讨论】:

  • 在谷歌上搜索异常时,您没有得到任何提示吗?

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


【解决方案1】:

您的实体配置在我看来是正确的。

正如@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();

应该这样做!

【讨论】:

  • 我在 .ThenInclude(x => x.AnswerStatusType) 中找不到 AnswerStatusType 的对象引用
  • 对不起,什么意思?你是说 IntelliSense 吗?
  • 考虑到实体框架核心有一些错误,我也在寻找另一种方式
  • 对,我看到了 IntelliSense 没有完成 ThenInclude 的问题。如果您发现任何与 EF Core 相关的错误,请通过在此处打开问题github.com/aspnet/EntityFrameworkCore/issues 让团队知道
  • @toxic 您应该按原样尝试建议的代码。有一个已知的 Intellisense 问题,但这与此代码是否编译/工作无关。
【解决方案2】:
var result = Context.Questions
             .Include(x=>x.Answers.Select(y=>y.AnswerType))
             .Where(x=>x.ID == QuestionidYouAreLookingFor)
             .ToList();

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

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

【讨论】:

  • 我收到以下错误 System.InvalidOperationException: 'The property expression 'question => {from AnswerDataModel y in question.Answers select [y].AnswerStatusType}' 无效。该表达式应表示属性访问:'t => t.MyProperty'。有关包含相关数据的更多信息,请参阅go.microsoft.com/fwlink/?LinkID=746393。'
  • 我找不到命名空间 System.Data.Entity,它是 EF Core 的一部分吗?
  • 我认为 EF Core 中存在错误,因此无法找到上述方法的参考
  • 需要另一种方法来实现这一点
  • EF-core 语法为Include-ThenInclude
猜你喜欢
  • 2023-03-29
  • 1970-01-01
  • 2020-06-16
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
  • 2016-10-10
  • 2020-08-06
相关资源
最近更新 更多