IQueryable conditional GroupBy

Viewed 44

I am attempting to build a groupby based on condition however I have been unsuccessful.

IQueryable<MyObject> query ..
var returnedVal = query.GroupBy(y => new {
                            Val1 = !first ? y.Val1 : null,
                            Val2 = !second ? y.Val2 : null })
                 .Select(x => new MyObject {
                            Val1 = !first ? y.Key.Val1 : null,
                            Val2 = !second ? y.Key.Val2 : null });
id Val1 Val2
1 Sta test1
2 Danny test2
3 Elle test2
4 Elle test3

Scenario 1: first: false second false
GroupBy both Val1 and Val2
Return all 4 rows

Scenario 2: first: true second false
GroupBy only Val2
Return 3 rows (test1, test2, test3)

Scenario 3: first: false second true
GroupBy only Val1
Return 3 rows (Sta, Danny, Elle)

Scenario 4: first: true second true
GroupBy nothing
Return nothing

My problem is that everytime either "first" or "second" is true Val1 and Val2 still gets included in the groupby of the query. Is setting Val1/Val2 to null in the GroupBy the right approach to exclude it from the groupby entirely?

1 Answers

I don't see the actual problem, because you don't tell if the result is what you expect. If you just want to remove the unnecessary grouping, use an if:

if(condition){ queryWithBothProperties } else { queryWithOneProperty }

The bool flags are not related to the records, so you can easily leave them out of the query.

On that way the query might become more efficient:

if (first && second)
{
    // no grouping necessary since all would be null anyway
    result = query
        .Select(x => new MyObject { Val1 = x.Val1, Val2 = x.Val2 });
}
else if (first)
{
    result = query
        .GroupBy(x => x.Val2)
        .Select(g => new MyObject { Val1 = null, Val2 = g.Key });
}
else if (second)
{
    result = query
        .GroupBy(x => x.Val1)
        .Select(g => new MyObject { Val1 = g.Key, Val2 = null });
}
else
{
    // both are false, you want to group by both properties
    result = query
          .GroupBy(x => (x.Val1, x.Val2))
          .Select(x => new MyObject { Val1 = x.Key.Val1, Val2 = x.Key.Val2 });
}
Related