Reputation: 99
I have data table "Car" which have 3 cols (owner, carType, colour). My question is how can i make the grouping portion more dynamic by using reflection. my idea is add the grouping col in to array, then use the reflection on the query grouping part. however i was struck at the reflection..
var gcols = new string[] { "owner", "carType" };
var reseult = dt.AsEnumerable()
.GroupBy(x => new
{
carType = x.Field<string>("carType"),
colour = x.Field<string>("colour")
})
.Select(x => new
{
CarType = x.Key.carType,
Colour = x.Key.colour,
count = x.Count()
})
.OrderBy(x => x.CarType).ToList();
Upvotes: 2
Views: 1033
Reputation: 380
Try this - using System.Linq.Dynamic.Core link
First, you need the data as IEnumerable - cast data table to list.
For example I declare this list:
IEnumerable<Customer> customers = new List<Customer>
{
new Customer{owner = "aa", carType = "T1", colour = "red" },
new Customer{owner = "aa", carType = "T1", colour = "green"},
new Customer{owner = "bb", carType = "T1", colour = "red"}
};
Get the list of column names for group.
var gcols = new string[] { nameof(Customer.owner), nameof(Customer.carType) };
Then use dynamic group
var grouped = customers.AsQueryable().GroupBy($"new({string.Join(",", gcols)})", "it");
List<List<Customer>> groups = new List<List<Customer>>();
foreach (var item in grouped)
{
var list = (item as IEnumerable<Customer>).ToList();
groups.Add(list);
}
If your columns to group are dynamic you need check if the key exists.
var result = groups
.Select(x => new
{
owner = gcols.Contains("owner") ? x.First().owner : string.Empty,
CarType = gcols.Contains("carType") ? x.First().carType : string.Empty,
Colour = gcols.Contains("colour") ? x.First().colour : string.Empty,
count = x.Count()
})
.OrderBy(x => x.CarType).ToList();
Upvotes: -1
Reputation: 13864
If you added this extension method to object:
public static T Field<T>(this object source, string FieldName)
{
var type = source.GetType();
var field = type.GetField(FieldName);
return (T)field.GetValue(source);
}
You'd be able to use the syntax you've posted in your code.
I've not added any safety checking here so it'll need cleaning up, but it'll get you going. Ideally you'd want to check that the type of field
is the same as T
and a few other checks.
Upvotes: 1