Dynamic Linq with dictionary keys

.net-4.0 c# dynamic-linq linq


I currently have a piece of code that takes a DataView, selects the values of a single column, groups by those values, then outputs the count (to get a histogram, of sorts):

string columnName;
var dataSource = grid.DataSource as System.Data.DataView;
var values = dataSource.OfType<System.Data.DataRowView>()
                       .Select(r => r[columnName]);

_GroupedRowCounts = values.GroupBy(r => r[columnName])
                          .ToDictionary(v => v.Key, v => v.Count());

That works fine, but turns out I need to group by an arbitrary number of columns that I don't know at compile time.

I assume I can use System.Linq.Dynamic for this, but I've found its documentation rather lacking (starting from: which of the GitHub projects is current?). I can apparently use DynamicExpression.CreateClass() to dynamically create a class with properties based on the columns I want to group by, something like:

List<DataColumn> columns;
Type dynamicDataClass = DynamicExpression.CreateClass(columns.Select(c => new DynamicProperty(c.ColumnName, c.DataType)));

However, I'm unclear about:

  • how do I then pass this class to a Select and GroupBy call? System.Linq.Dynamic exposes a Select() overload that takes a string — do I just pass the class's property names? How does System.Linq.Dynamic know to use the dynamically generated type?
  • how do I fill this with values? I know I can use Activator to do so manually, but is there a built-in way of mapping this to the values of the original objects, or do I need to custom-roll this?
  • am I even on the right track at all? The examples don't seem to use DynamicExpression, etc., but rather just strings.
6/25/2018 6:13:42 PM

Popular Answer

This answer is for if you would like to get around using an external library. This is going to be a little bit more inefficient than using a library. It seems that there is also another library that you can try called Linq.Dynamic.Core. It seems a little more robust.

I would convert the result of your linq query to a list of type Dictionary. Using the top answer from this post: LINQ query to return a Dictionary<string, string>

Then you can sort doing something like this:

List<Dictionary<string, string>> list = new List<Dictionary<string, string>>();

list.OrderBy(x => x["columnName"]).ToList();
6/25/2018 6:42:09 PM

Related Questions

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow