如何将 where 子句添加到 ThenInclude
Posted
技术标签:
【中文标题】如何将 where 子句添加到 ThenInclude【英文标题】:How to add where clause to 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(); 【参考方案1】:不支持在Include
或ThenInclude
中过滤。使用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();
【讨论】:
以上是关于如何将 where 子句添加到 ThenInclude的主要内容,如果未能解决你的问题,请参考以下文章