【问题标题】:How to add where clause to ThenInclude如何将 where 子句添加到 ThenInclude
【发布时间】:2017-02-06 08:28:25
【问题描述】:

我有 3 个实体:

Questionnaire.cs:

public class Questionnaire
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Question> Questions { get; set; }
}

Question.cs:

public class Question
{
    public int Id { get; set; }
    public string Text { get; set; }
    public ICollection<Answer> Answers { get; set; }
}

Answer.cs

public class Answer
{
    public int Id { get; set; }
    public string UserId { get; set; }
    public string TextAnswer { get; set; }
}

所以我保存了带有答案的问卷,但现在我想检索带有问题及其答案的过滤问卷。所以我为此写了linq,但它给我一个错误,我做错了什么吗?这是一个例子:

questionnaire = _context.Questionnaires.Include(qn => qn.Questions)
.ThenInclude(question => question.Answers.Where(a => a.UserId == userId))
.FirstOrDefault(qn => qn.Id == questionnaireId);

我得到了

Message = "属性表达式 'q => {来自 q.Answers 中的答案 a 其中 Equals([a].UserId, __userId_0) select [a]}' 无效。这 表达式应表示属性访问:'t => t.MyProperty'。

任何想法如何解决这个问题?

【问题讨论】:

  • 你能告诉我你的查询是什么吗?
  • 每个问卷都有问题,问题有答案,我需要通过userId过滤这些问题的答案。
  • 我将您的模型类更改为在您的 answer 中有一个 Question 的导航属性。 var问卷= ctx.Answers.Include(q=>q.Question).Where(a =>a.UserId=="1").ToList();

标签: c# entity-framework linq asp.net-core entity-framework-core


【解决方案1】:

不支持在IncludeThenInclude 中过滤。使用Select创建投影:

questionnaire = _context.Questionnaires
    .Select(n => new Questionnaire
    {
        Id = n.Id,
        Name = n.Name,
        Questions = n.Questions.Select(q => new Question
        {
           Id = q.Id,
           Text = q.Text,
           Answers = q.Where(a => a.UserId == userId).ToList()
        }).ToList()
    })
    .FirstOrDefault(qn => qn.Id == questionnaireId);

关于这个问题有个github issue:https://github.com/aspnet/EntityFramework/issues/3474

【讨论】:

    【解决方案2】:

    我认为您需要在答案中有问题的导航属性,因为答案应该有问题 Id 。你已经有了这个 FK,你只需要一个导航属性

    您的模型类如下所示

    public class Answer
    {
        public int Id { get; set; }
        public string UserId { get; set; }
        public string TextAnswer { get; set; }
        // added in model
        public Question Question { get; set; }
    } 
    

    像这样查询

      var answers = ctx.Answers.Include(q=>q.Question).Where(a =>a.UserId=="1").ToList();
    

    【讨论】:

      【解决方案3】:

      您可以在内存中过滤导航属性:

      var questionnaire= _context.Questionnaire.FirstOrDefault(qn => qn.Id == questionnaireId);
      
      questionnaire.Answers = _context.Entry(questionnaire)
       .Collection(b => b.Answers )
       .Query()
       .Where(a => a.UserId == userId).ToList();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-07
        • 2019-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多