// Copyright (c) MudBlazor 2021 // MudBlazor licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Linq.Expressions; namespace Connected.Components; public class AggregateDefinition { public AggregateType Type { get; set; } = AggregateType.Count; public string DisplayFormat { get; set; } = "{value}"; public Func, string> CustomAggregate { get; set; } private AggregateType? _cachedType; private Func _compiledAvgExpression; private Func _compiledMinMaxExpression; private Func _compiledSumExpression; public string GetValue(string field, IEnumerable items) { if (items == null || items.Count() == 0) { return DisplayFormat.Replace("{value}", "0"); } object value = null; if (_cachedType != Type) { _cachedType = Type; if (Type == AggregateType.Avg) { var parameter = Expression.Parameter(typeof(T), "x"); var f = Expression.Convert(Expression.Property(parameter, typeof(T).GetProperty(field)), typeof(decimal)); _compiledAvgExpression = Expression.Lambda>(f, parameter).Compile(); value = items.Average(_compiledAvgExpression); } else if (Type == AggregateType.Count) { value = items.Count(); } else if (Type == AggregateType.Custom) { return CustomAggregate.Invoke(items); } else if (Type == AggregateType.Max) { var parameter = Expression.Parameter(typeof(T), "x"); var f = Expression.Convert(Expression.Property(parameter, typeof(T).GetProperty(field)), typeof(object)); _compiledMinMaxExpression = Expression.Lambda>(f, parameter).Compile(); value = items.Max(_compiledMinMaxExpression); } else if (Type == AggregateType.Min) { var parameter = Expression.Parameter(typeof(T), "x"); var f = Expression.Convert(Expression.Property(parameter, typeof(T).GetProperty(field)), typeof(object)); _compiledMinMaxExpression = Expression.Lambda>(f, parameter).Compile(); value = items.Min(_compiledMinMaxExpression); } else if (Type == AggregateType.Sum) { var parameter = Expression.Parameter(typeof(T), "x"); var f = Expression.Convert(Expression.Property(parameter, typeof(T).GetProperty(field)), typeof(decimal)); _compiledSumExpression = Expression.Lambda>(f, parameter).Compile(); value = items.Sum(_compiledSumExpression); } } else { if (Type == AggregateType.Avg) { value = items.Average(_compiledAvgExpression); } else if (Type == AggregateType.Count) { value = items.Count(); } else if (Type == AggregateType.Custom) { return CustomAggregate.Invoke(items); } else if (Type == AggregateType.Max) { value = items.Max(_compiledMinMaxExpression); } else if (Type == AggregateType.Min) { value = items.Min(_compiledMinMaxExpression); } else if (Type == AggregateType.Sum) { value = items.Sum(_compiledSumExpression); } } return DisplayFormat.Replace("{value}", (value ?? "").ToString()); } public static AggregateDefinition SimpleAvg() { return new AggregateDefinition { Type = AggregateType.Avg, DisplayFormat = "Average {value}" }; } public static AggregateDefinition SimpleCount() { return new AggregateDefinition { Type = AggregateType.Count, DisplayFormat = "Total {value}" }; } public static AggregateDefinition SimpleMax() { return new AggregateDefinition { Type = AggregateType.Max, DisplayFormat = "Max {value}" }; } public static AggregateDefinition SimpleMin() { return new AggregateDefinition { Type = AggregateType.Min, DisplayFormat = "Min {value}" }; } public static AggregateDefinition SimpleSum() { return new AggregateDefinition { Type = AggregateType.Sum, DisplayFormat = "Sum {value}" }; } }