我有一个调查应用程序,它从连接到SQL Server数据库的应用程序服务中检索问题和答案。调查分为几页,每一页都分为几个部分。当用户提交了一个页面时,我想将各个部分标记为完整,这样用户就无法重新提交他的答案。
我正在尝试编写一个LINQ查询,将每个部分中的问题数量与答案为的问题数量进行比较,看看我们是否应该将调查部分标记为已完成。请注意,有些问题可能有多个答案,所以我在选择答案时使用.Distinct()
,而不仅仅是选择答案的数量。
这是用于选择问题数量的LINQ查询,这个查询总是正确的;它只是在一个部分中返回问题的id。
var questionsInSection = await _questionRepository.GetAll()
.Where(q => q.SurveySectionId == surveySectionId)
.Select(dto => new { dto.Id }).ToListAsync();
以下是我所做的,试图在一个部分中获得问题的数量和答案。
首先,我需要在与令牌相关联的存储库中获得所有答案。该令牌唯一标识该调查受访者。
问题通过QuestionOptions
表链接到答案,所以我也包括了这一点。它既有一个QuestionId
,也有一个构成答案的OptionChoicesId
。
我对我的问题列表执行内部联接,因此select将只获得两个表中都存在的id。尽管如此,下面的LINQ查询返回存储库中所有答案的id,而不仅仅是一个部分中存在的答案的id。
var answersInSection = await (from a in _answerRepository.GetAll()
.Include(t => t.Token).Include(qo => qo.QuestionOptions)
.Where(a => a.Token.tokenText == input.Token)
join q in questionsInSection
on a.QuestionOptions.QuestionId equals q.Id into QandA
select new
{
Id = QandA.Distinct()
}).ToListAsync();
如何从我的LINQ查询中获得带有答案的问题数量的ID?以下是相关的数据库模式。
QuestionOptions table Questions table Answer table
================================== =========================== =============
id | QuestionId | OptionsChoicesId id | Text | SurveySectionId id | QuestionOptionsId | tokenId
此SQL实现了正确的结果:
SELECT DISTINCT [Answer].[Id]
FROM [Portal].[dbo].[Answer]
INNER JOIN [Portal].[dbo].[QuestionOptions]
ON [Portal].[dbo].[QuestionOptions].[Id] = [Portal].[dbo].[Answer].[QuestionOptionsId]
INNER JOIN [Portal].[dbo].[Question]
ON [Portal].[dbo].[Question].[Id] = [Portal].[dbo].[QuestionOptions].[QuestionId]
WHERE [Portal].[dbo].[Question].[SurveySectionId] = 2
我发现了问题所在。使用into
将操作从SQL中的JOIN
更改为GroupJoin
。我想定期加入,所以一切都很顺利。以下是林克的正确陈述。
var questionsInSection = await _questionRepository.GetAll()
.Where(q => q.SurveySectionId == surveySectionId).ToListAsync();
var answersInSection = await (from a in _answerRepository.GetAll()
.Include(t => t.Token).Include(qo => qo.QuestionOptions)
.Where(a => a.Token.tokenText == input.Token)
join q in questionsInSection on a.QuestionOptions.QuestionId equals q.Id
select new
{
a.Id
}).Distinct().ToListAsync();