Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ GroupBy with a dynamic group of columns

Tags:

c#

linq

group-by

I have a table like this:

 variety category  quantity
----------------------------------------------
  rg      pm         10
  gs      pm          5
  rg      com         8

I want to make a GroupBy based on these bool parameters:

  • IncludeVariety
  • IncludeCategory

eg:

IncludeVariety = true;
IncludeCategory = true;

would return this:

 variety category  quantity
----------------------------------------------
  rg      pm         10
  gs      pm          5
  rg      com         8

and this:

IncludeVariety = true;
IncludeCategory = false;

would return this:

  variety category  quantity
----------------------------------------------
    rg      -         18
    gs      -          5

and this:

IncludeVariety = false;
IncludeCategory = true;

would return this:

  variety category  quantity
----------------------------------------------
     -      pm         15
     -      com         8

You get the idea...

Question: How can I achieve this with LINQ?

Important: I've reduced the problem to two bool variables (IncludeVariety and IncludeCategory) but in reality I will be having more columns (say five)

I can't figure out how to generate the query dynamically (the .GroupBy and the .Select):

 rows.GroupBy(r => new { r.Variety, r.Category })
 .Select(g => new 
  {
        Variety = g.Key.Variety,
        Category = g.Key.Category,
        Quantity = g.Sum(a => a.Quantity),
  });

 rows.GroupBy(r => new { r.Category })
 .Select(g => new 
  {
        Variety = new {},
        Category = g.Key.Category,
        Quantity = g.Sum(a => a.Quantity),
  });

 rows.GroupBy(r => new { r.Variety })
 .Select(g => new 
  {
        Variety = g.Key.Variety,
        Category = new {},
        Quantity = g.Sum(a => a.Quantity),
  });

A similar thing I've done in the past is concatenate Where's, like:

  var query = ...

  if (foo) {
       query = query.Where(...)
  }

  if (bar) {
       query = query.Where(...)
  }

  var result = query.Select(...)

Can I do something like that here?

like image 483
sports Avatar asked Oct 22 '15 16:10

sports


1 Answers

var results=items
  .Select(i=>
    new {
      variety=includevariety?t.variety:null,
      category=includecategory?t.category:null,
      ...
    })
  .GroupBy(g=>
    new { variety, category, ... }, g=>g.quantity)
  .Select(i=>new {
    variety=i.Key.variety,
    category=i.Key.category,
    ...
    quantity=i.Sum()
  });

shortened:

var results=items
  .GroupBy(g=>
    new {
      variety=includevariety?t.variety:null,
      category=includecategory?t.category:null,
      ... 
    }, g=>g.quantity)
  .Select(i=>new {
    variety=i.Key.variety,
    category=i.Key.category,
    ...
    quantity=i.Sum()
  });
like image 187
Robert McKee Avatar answered Oct 09 '22 21:10

Robert McKee