我有一个C#.NET应用程序,想在多种情况下进行分组依据。 我有一个这样的列表:
var testq = new List<TestQuestion>()
{
new TestQuestion
{
Id = 1,
QuestionId = 1,
SelectedAnswerId = null
},
new TestQuestion
{
Id = 2,
QuestionId = 2,
SelectedAnswerId = 1
},
new TestQuestion
{
Id =3,
QuestionId = 1,
SelectedAnswerId = 1
},
new TestQuestion
{
Id = 4,
QuestionId = 3,
SelectedAnswerId = 5
},
new TestQuestion
{
Id = 5,
QuestionId = 1,
SelectedAnswerId = 2
},
new TestQuestion
{
Id = 6,
QuestionId = 3,
SelectedAnswerId = 3
},
new TestQuestion
{
Id =7,
QuestionId = 4,
SelectedAnswerId = null
},
new TestQuestion
{
Id =8,
QuestionId = 5,
SelectedAnswerId = null
},
};
我的代码是:
var result = testq
.Where(p => p.SelectedAnswerId.HasValue)
.GroupBy(p => p.QuestionId)
.Select(p => p.FirstOrDefault())
.ToList();
现在,结果ID为(2,3,4) 但是结果不正确...
结果应该是这样的: ID->(2,3,4,7,8)
我要根据QuestionID字段对结果进行分组,并且第一个没有(SelectedAnswerId)字段值的记录为空,
此外,无论输出中字段的值(SelectedAnswerId)如何,都记录其中问题ID仅存在一次的记录。就是说,列表中的最后两项
请引导我...
答案 0 :(得分:2)
尝试一下:
var result = testq
.Where(p => p.SelectedAnswerId.HasValue || testq.Count(x => x.QuestionId == p.QuestionId) == 1)
.GroupBy(p => p.QuestionId)
.Select(p => p.FirstOrDefault())
.Distinct()
.ToList();
答案 1 :(得分:0)
您必须在SelectedAnswerId
而不是Select
子句中过滤Where
。请尝试以下
var result = testq
.GroupBy(p => p.QuestionId)
.Select(p =>
{
var grouped = p.ToList(); //Get the groupBy list
TestQuestion testQuestion = grouped.FirstOrDefault(x => x.SelectedAnswerId.HasValue); //Get anything with AnswerId
return testQuestion ?? grouped.FirstOrDefault(); //If not not available with Answer then get the First or Default value
})
.ToList();
C# Fiddle和测试数据。
答案 2 :(得分:0)
尽管在GroupBy之后,每个组中元素的顺序都得到了明确定义(请参见Enumerable.GroupBy,但似乎您想要的元素不是每个组中的第一个元素。
您希望每个组的First元素具有一个不为空的SelectedAnswerId,或者如果没有这样的元素,则希望每个组的First元素具有一个不为空的SelectedAnswerId。
如何?
var result = testQ.GroupBy(question => question.QuestionId);
// every group contains a sequence of questions with same questionId
// select the ones with a null SelectedAnswerId and the ones with a non-null value
.Select(group => new
{
NullSelectedAnswer = group
.Where(group.SelectedAnswerId == null)
.FirstOrDefault(),
NonNullselectedAnswer = group
.Where(group.SelectedAnswerId != null)
.FirstOrDefault(),
})
// if there is any NonNullSelectedAnswer, take that one, otherwise take the null one:
.Select(selectionResult => selectionResult.NonNullSelectedAnswer ??
selectionResult.NullSelectedAnswer);