I am trying to create a way to run some dynamic linq on a data table, the code I have pasted is test code not my full code that I am working on, but I think it is enough to get across what I am attempting to do.
Essentially I want to add a second parameter to the the method that will contain an expression that can be used to replace the r => r.Field("field").
public string GetStringValueFromData(DataTable data)
{
switch (this.MethodType)
{
case (LabelMethodType.Count):
return data.AsEnumerable().Select(r => r.Field<string>("sometextfield")).Count().ToString();
case (LabelMethodType.Sum):
return data.AsEnumerable().Sum(r => r.Field<decimal>("somenumberfield")).ToString();
case (LabelMethodType.Average):
return data.AsEnumerable().Average(r => r.Field<decimal>("anotherfield")).ToString();
}
return string.Empty;
}
so essentially the method would look something like this. But of course I have tried this and it does not even compile.
public string GetStringValueFromData(DataTable data, Expression<Func<DataRow, object>> expression)
{
switch (this.MethodType)
{
case (LabelMethodType.Count):
return data.AsEnumerable().Select(expression).Count().ToString();
case (LabelMethodType.Sum):
return data.AsEnumerable().Sum(expression).ToString();
case (LabelMethodType.Average):
return data.AsEnumerable().Average(expression).ToString();
}
return string.Empty;
}
Does anyone possibly know what type could make the parameter for this to work, so that it will accept something like r => r.Field("sometextfield") or r => r.Field("somenumberfield") or have suggestions of an alternative approach.
Thanks
CD
This should work as expected:
public string GetStringValueFromData(DataTable data, Func<DataRow, object> expression)
{
switch (this.MethodType)
{
case (LabelMethodType.Count):
return data.AsEnumerable().Select(expression).Count().ToString();
case (LabelMethodType.Sum):
return data.AsEnumerable().Select(expression).Cast<int>().Sum().ToString();
case (LabelMethodType.Average):
return data.AsEnumerable().Select(expression).Cast<int>().Average().ToString();
}
return string.Empty;
}
Notes:
You don't need to use Expression< Func<> >, you can use just Func<>.
The Select expression for the Count case is not necessary, the projection will never affect the count.