I want to populate a drop down with the public properties of a particular object, which I have done fine. But now when the user selects the value from the dropdown, I want it to group the DB table results by that column. I have tried using LINQ but I can only figure out how to explicitly group by an instance variables property, not by a reflection property. This is my method - the parameter passed in is the string name of the property. Eg it will be "Country" if the user wants to group by Customer.Country, it will be "State" if the user wants to group by Customer.State. But at the moment I have hard coded to group by "State" as I cannot figure out how to use the string value passed in with my LINQ query
private void DisplayReportAction(string category)
{
if (!string.IsNullOrEmpty(category))
{
SelectedCategory = category;
_summaries.Clear();
foreach (var custGroup in _customerInterface.CustomerInterface.GetAllCustomers().GroupBy(c => c.State)
.Select(group => new
{
Category = group.Key,
Count = group.Count()
})
.OrderBy(x => x.Category))
{
_summaries.Add(new CustomerReportSummaryViewModel(custGroup.Category, custGroup.Count));
}
ReportVisibility = Visibility.Visible;
}
}
You can use Reflection if you are using LINQ to Objects, for instance you can use this:
_customerInterface.CustomerInterface.GetAllCustomers()
.GroupBy(c => c.GetType().GetProperty(category).GetValue(c, null))
If you are using Linq To Sql then an alternative is to use dynamic queries, check this link
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
You may build expression dynamically:
Expression<Func<Customer,T>> buildExpression<T>(string category)
{
//First build parameter of lambda ( 'c =>' part of expression)
ParameterExpression param = Expression.Parameter(typeof(Customer), "c");
//Then body of expression : ' => c.category'
Expression<Func<Customer, T>> exp = Expression.Lambda<Func<Customer, T>>(Expression.Property(param, category), param);
return exp;
}
And finally, call
_customerInterface.CustomerInterface.GetAllCustomers()
.GroupBy(buildExpression(category))
EDIT:
Well, sorry you still have to know the type of property to give T type parameter to buildExpression
function
There are ways to do this, using for example GetProperty(category).PropertyType
and then call MakeGenericMethod
on GetType().GetMethod("buildExpression<>")
, but this requires a little more work.
Anyway, you'll have to find a way to build CustomerReportSummaryViewModel
from this type.
I don't know your use case, but you maybe all categories properties are of the same type, so you could hard-code it ?
If you are interested, and can't find a proper way to do it let me know I'll try to write a proper solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With