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?
CodePudding user response:
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 });
}
CodePudding user response:
It's really hard to tell what you're trying to solve without an example value of Val1 and Val2, and the expected output. That said, here's some Linqpad code that might be what you're going for - or at least provide a starting point to describe a few test cases...
var list = new List<(int id, string val1, string val2)>()
{(1, "Sta", "test1"),
(2, "Danny", "test2"),
(3, "Elle", "test2"),
(4, "Elle", "test3")};
var first = "Danny";
var second = "test3";
list
.Where(row => row.val1 != first && row.val2 != second)
.GroupBy(row => new { row.val1, row.val2 })
.Select(row => new
{
Val1 = row.Key.val1,
Val2 = row.Key.val2,
RowVals = string.Join(',', row)
})
.Dump();
Results
Val1 | Val2 | RowVals |
---|---|---|
Sta | test1 | 1, Sta, test1 |
Elle | test2 | 3, Elle, test2 |