XN16
XN16

Reputation: 5889

Linq grouping into list

I have the following select query in linq:

var something = 
    from te in taskEvidences
    join e in evidences on te.EvidenceId equals e.Id
    join tr in taskRequirements on te.TaskListId equals tr.TaskListId
    join r in newSelectableModule.Requirements on tr.RequirementListId equals r.Requirement.Id
    select new
    {
        Evidence = e,
        RequirementIndices = r.Index
    };

Currently it selects an Evidence object along with several Index (int) values, so for example I might get 5 records back, all with the same Evidence object and 5 different indices.

What I want to do it just return a single record with the Evidence object and a List<int> of the indices. I attempted to use grouping, but I keep getting errors about the type can't be inferred from the usage. This is one such attempt:

group new {e, r} by new {e}
into g
select new
{
    Evidence = g.Key,
    RequirementIndices = g.SelectMany(x => x.r.Index)
};

The error occurs around the SelectMany being assigned to the RequirementIndices property. I've tried several suggests I've found online, but none of them have helped. I assume it is a small error on my part, but I'm going code blind now!

Update:

Exact error:

The type arguments for method 'Enumerable.SelectMany(IEnumerable, Func>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Upvotes: 0

Views: 85

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727077

You should be able to produce the same grouped result by avoiding a join in the top level:

var something = 
    from te in taskEvidences
    join e in evidences on te.EvidenceId equals e.Id
    select new
    {
        Evidence = e,
        RequirementIndices = (
            from tr in taskRequirements
            join r in newSelectableModule.Requirements on tr.RequirementListId equals r.Requirement.Id
            where te.TaskListId equals tr.TaskListId
            select r.Index
        ).ToList()
    };

Now the list is selected through a correlated subquery with a join, which eliminates creation of "duplicates" of the parent record. It should have the same performance as the original query.

Upvotes: 0

XN16
XN16

Reputation: 5889

As @JeroenvanLangen suggested in the comment on my question, I didn't need SelectMany only a Select:

var something = 
    from te in taskEvidences
    join e in evidences on te.EvidenceId equals e.Id
    join tr in taskRequirements on te.TaskListId equals tr.TaskListId
    join r in newSelectableModule.Requirements on tr.RequirementListId equals r.Requirement.Id
    group new { e, r } by new { e }
    into g
    select new
    {
        Evidence = g.Key,
        RequirementIndices = g.Select(x => x.r.Index).ToList()
    };

Upvotes: 1

Related Questions