You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Connected.Components/Components/DataGrid/AggregateDefinition.cs

146 lines
4.5 KiB

2 years ago
// 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<T>
{
public AggregateType Type { get; set; } = AggregateType.Count;
public string DisplayFormat { get; set; } = "{value}";
public Func<IEnumerable<T>, string> CustomAggregate { get; set; }
private AggregateType? _cachedType;
private Func<T, decimal> _compiledAvgExpression;
private Func<T, object> _compiledMinMaxExpression;
private Func<T, decimal> _compiledSumExpression;
public string GetValue(string field, IEnumerable<T> 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<Func<T, decimal>>(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<Func<T, object>>(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<Func<T, object>>(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<Func<T, decimal>>(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<T> SimpleAvg()
{
return new AggregateDefinition<T>
{
Type = AggregateType.Avg,
DisplayFormat = "Average {value}"
};
}
public static AggregateDefinition<T> SimpleCount()
{
return new AggregateDefinition<T>
{
Type = AggregateType.Count,
DisplayFormat = "Total {value}"
};
}
public static AggregateDefinition<T> SimpleMax()
{
return new AggregateDefinition<T>
{
Type = AggregateType.Max,
DisplayFormat = "Max {value}"
};
}
public static AggregateDefinition<T> SimpleMin()
{
return new AggregateDefinition<T>
{
Type = AggregateType.Min,
DisplayFormat = "Min {value}"
};
}
public static AggregateDefinition<T> SimpleSum()
{
return new AggregateDefinition<T>
{
Type = AggregateType.Sum,
DisplayFormat = "Sum {value}"
};
}
}