Search code examples
c#linqasp.net-core

GroupBy dynamic list on multiple properties by using reflection


I have a class that defines some settings, one of this settings are the properties to group the list that you want to group by:

object of class MySetting

MySetting setting = new()
{
 Groupby = $"{nameof(MyCss.Color)}, {nameof(MyCss.Width)}",
 //.....
}

Now I have a dynamic list and I want to send this list as parameter with object setting to a method like ApplySetting, this method has to check if Groupby not a null and group my list:

public ApplySetting(List<TItem> myList, MySetting setting)
{
  if(setting.Groupby != null)
  {
   var arr = setting.Groupby.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
    //do some this like, this wrong !
    var groubs = myList.GroupBy(x => arr.ForEach(y => GetPropertyValue(y, x, x.GetType())))
   
  }
}

Note: GetPropertyValue is a method that get value from object by using reflection.
Thanks for any help.


Solution

  • This is not solution with reflection you asked for but hack, but maybe it can serve you.

    It uses lib System.Linq.Dynamic.Core and converts list to IQueryable.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Dynamic.Core;
            
    public class MySetting {
        public string Groupby { get; set; }
    }
    
    public class ToGroupType {
        public string Color { get; set; }
        public string Width { get; set; }
    }
    
    public class Program
    {
        public static void Main()
        {
            MySetting setting = new()
            {
             Groupby = $"Color, Width",
             //.....
            };
             static void  ApplySetting<TItem>(List<TItem> myList, MySetting setting)
            {
              if(setting.Groupby != null)
              {
               //do some this like, this wrong !
                var groubs = myList.AsQueryable().GroupBy($"new ({setting.Groupby})", "it").Select($"new (it.Key as Key , Count() as Count)").ToDynamicList();
                Console.WriteLine(string.Join(",", groubs));
                //result:  Key = { Color = Red, Width = 10 }, Count = 2 },{ Key = { Color = Blue, Width = 10 }, Count = 2 },{ Key = { Color = Blue, Width = 15 }, Count = 1 }
              }
            }
            ApplySetting(new List<ToGroupType>(){
                new ToGroupType{Color = "Red", Width="10"},
                new ToGroupType{Color = "Red", Width="10"},
                new ToGroupType{Color = "Blue", Width="10"},
                new ToGroupType{Color = "Blue", Width="10"},
                new ToGroupType{Color = "Blue", Width="15"},
                
            }, setting);
    }}