多个Group By LINQ扩展方法



我有一个C#.NET应用程序,希望在多个条件下执行Group By。我有一个这样的列表:

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(字段值的第一条记录为空,

此外,问题ID只存在一次的记录,而与输出中字段(SelectedAnswerId(的值无关。也就是说,列表中的最后两项

请引导我…

试试这个:

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();

C#Fiddle

您必须在Select中而不是在Where子句中筛选SelectedAnswerId。试试下面的,

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#篡改测试数据。

尽管在GroupBy之后,每个组中元素的顺序都得到了公平的定义(请参见Enumerable.GroupBy,但您想要的元素似乎不是每个组中的第一个。

您希望每个组的First元素具有非null的SelectedAnswerId,或者如果没有这样的元素,则希望每个组中的First元素都具有null的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);

最新更新