Sam*_*yan 0 c# linq dynamic telerik
在我的项目中,我使用 Telerik RadGridView 控件,其 ItemSource 是动态对象列表(派生自 DynamicObject)。
我打算使用 AggregateFunctions,如 SumFunction、MinFunction,但它在从动态属性获取值的列中崩溃。如果我是正确的,那是因为 Linq 扩展,而不是 Telerik。
这个问题有什么解决方法吗?
更新
模型类看起来像这样
public class SampleModel : DynamicObject
{
// some properties
}
Run Code Online (Sandbox Code Playgroud)
来源是这样的:
myGrid.ItemsSource = new List<SampleModel> { // some model items };
Run Code Online (Sandbox Code Playgroud)
XAML 是:
<telerik:RadGridView ShowColumnFooters="True" AutoGenerateColumns="False" x:Name="myGrid">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding p1}">
<telerik:GridViewDataColumn.AggregateFunctions>
<telerik:SumFunction />
</telerik:GridViewDataColumn.AggregateFunctions>
</telerik:GridViewDataColumn>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
Run Code Online (Sandbox Code Playgroud)
其中p1是动态属性
异常消息是:
类型“System.Linq.Enumerable”上的泛型方法“Sum”与提供的类型参数和参数不兼容。如果方法是非泛型的,则不应提供类型参数。
我通过创建自己的聚合函数并手动在其中构建表达式解决了这个问题(来源:Telerik support)。
Sum() 函数的代码是:
public class CustomSumFunction : EnumerableSelectorAggregateFunction
{
protected override string AggregateMethodName
{
get { return "Sum"; }
}
protected override Type ExtensionMethodsType
{
get
{
return typeof(CustomAggregateFunctions);
}
}
}
public static class CustomAggregateFunctions
{
public static TValue Sum<T, TValue>(IEnumerable<T> source, Func<T, TValue> selector)
{
return source.Select(selector).Aggregate((t1, t2) =>
{
Expression expr = Expression.Add(Expression.Constant(t1, t1.GetType()), Expression.Constant(t2, t2.GetType()));
Expression conversion = Expression.Convert(expr, typeof(TValue));
return Expression.Lambda<Func<TValue>>(conversion).Compile()();
});
}
public static decimal? Sum<TSource>(IEnumerable<TSource> source, Func<TSource, decimal?> selector)
{
return source.Sum(selector);
}
public static decimal Sum<TSource>(IEnumerable<TSource> source, Func<TSource, decimal> selector)
{
return source.Sum(selector);
}
public static double? Sum<TSource>(IEnumerable<TSource> source, Func<TSource, double?> selector)
{
return source.Sum(selector);
}
public static double Sum<TSource>(IEnumerable<TSource> source, Func<TSource, double> selector)
{
return source.Sum(selector);
}
public static float? Sum<TSource>(IEnumerable<TSource> source, Func<TSource, float?> selector)
{
return source.Sum(selector);
}
public static float Sum<TSource>(IEnumerable<TSource> source, Func<TSource, float> selector)
{
return source.Sum(selector);
}
public static int? Sum<TSource>(IEnumerable<TSource> source, Func<TSource, int?> selector)
{
return source.Sum(selector);
}
public static int Sum<TSource>(IEnumerable<TSource> source, Func<TSource, int> selector)
{
return source.Sum(selector);
}
public static long? Sum<TSource>(IEnumerable<TSource> source, Func<TSource, long?> selector)
{
return source.Sum(selector);
}
public static long Sum<TSource>(IEnumerable<TSource> source, Func<TSource, long> selector)
{
return source.Sum(selector);
}
}
Run Code Online (Sandbox Code Playgroud)