GridCustomDataSourceSummaryInfo.SummaryType Property
Specifies the aggregation function of a summary item.
Namespace: DevExpress.Blazor
Assembly: DevExpress.Blazor.Grid.v26.1.dll
NuGet Package: DevExpress.Blazor
Declaration
public GridSummaryItemType SummaryType { get; }
Property Value
| Type | Description |
|---|---|
| GridSummaryItemType | A GridSummaryItemType value that specifies the aggregation function of a summary item. |
Available values:
| Name | Description |
|---|---|
| Sum | Calculates the sum of all values in a column. |
| Min | Calculates the minimum value of all values in a column. |
| Max | Calculates the maximum value of all values in a column. |
| Count | Calculates the number of values in a column. |
| Avg | Calculates the average of all values in a column. |
| Custom | Uses a custom algorithm to calculate a summary value. |
| None | Does not calculate a summary value. |
Remarks
If standard data binding modes do not meet specific business requirements, you can implement your own data provider. To do so, create a GridCustomDataSource descendant and assign it to the Grid or TreeList component’s Data property.
The following code snippet implements a custom data provider’s GetGroupInfoAsync method:
using DevExpress.Blazor;
using DevExpress.Data.Filtering;
using DevExpress.Data.Filtering.Helpers;
using CustomDataSource.Models;
using System.Collections;
using System.Linq.Expressions;
using DevExpress.Data.Linq;
using DevExpress.Data.Linq.Helpers;
using Microsoft.EntityFrameworkCore;
namespace CustomDataSource.Services;
public class OrdersDataSource : GridCustomDataSource, IDisposable {
protected override Type DataItemType => typeof(Order);
private readonly NorthwindContext _context;
private bool _disposed = false;
public OrdersDataSource(IDbContextFactory<NorthwindContext> contextFactory) {
_context = contextFactory.CreateDbContext();
}
// ...
public override async Task<IList<GridCustomDataSourceGroupInfo>> GetGroupInfoAsync(GridCustomDataSourceGroupingOptions options,
CancellationToken cancellationToken) {
var filteredQuery = ApplyFiltering(options.FilterCriteria, _context.Orders);
var summaryQuery = GetGroupByAndSelectQuery(options.SummaryInfo, filteredQuery, false, options.FieldName);
var resultList = await summaryQuery.ToListAsync(cancellationToken);
var groupInfoList = new List<GridCustomDataSourceGroupInfo>();
foreach (var result in resultList) {
var groupInfo = new GridCustomDataSourceGroupInfo() { Value = result["Value"], DataItemCount = (int)result["DataItemCount"] };
var summaryList = new List<object>();
foreach (var kvp in result) {
if (kvp.Key.StartsWith("Summary_")) {
summaryList.Add(kvp.Value);
}
}
groupInfo.SummaryValues = summaryList;
groupInfoList.Add(groupInfo);
}
return options.DescendingSortOrder
? groupInfoList
.OrderByDescending(g => g.Value)
.ToList()
: groupInfoList
.OrderBy(g => g.Value)
.ToList();
}
// ...
private static IQueryable<Order> ApplyFiltering(CriteriaOperator criteria, IQueryable<Order> queryableSource) {
return !criteria.ReferenceEqualsNull()
? (IQueryable<Order>)queryableSource.AppendWhere(
new CriteriaToEFExpressionConverter(queryableSource.Provider.GetType()), criteria)
: queryableSource;
}
// ...
private static IQueryable<Dictionary<string, object>> GetGroupByAndSelectQuery(IReadOnlyList<GridCustomDataSourceSummaryInfo> summaryInfoList,
IQueryable<Order> queryableSource, bool totalSummary, string groupedFieldName = "") {
IQueryable groupedQuery;
Type groupedPropertyType;
if (totalSummary) {
groupedPropertyType = typeof(int);
groupedQuery = queryableSource.GroupBy(x => 1);
} else {
var parameter = Expression.Parameter(typeof(Order));
var property = Expression.Property(parameter, groupedFieldName);
groupedPropertyType = property.Type;
var groupLambda = Expression.Lambda(property, parameter);
var groupByCall = Expression.Call(typeof(Queryable), "GroupBy", new[] { typeof(Order), groupedPropertyType },
queryableSource.Expression, groupLambda);
groupedQuery = queryableSource.Provider.CreateQuery(groupByCall);
}
var groupType = typeof(IGrouping<,>).MakeGenericType(groupedPropertyType, typeof(Order));
var group = Expression.Parameter(groupType);
// defining a dictionary that will hold group info
var dictItems = new List<ElementInit>();
var addMethod = typeof(Dictionary<string, object>).GetMethod("Add");
if (!totalSummary) {
dictItems.AddRange(new List<ElementInit> {
Expression.ElementInit(addMethod, Expression.Constant("Value"),
Expression.Convert(Expression.Property(group, "Key"), typeof(object))
),
Expression.ElementInit(addMethod, Expression.Constant("DataItemCount"),
Expression.Convert(Expression.Call(typeof(Enumerable), "Count",
new[] { typeof(Order) }, group), typeof(object))
)
});
}
for (int i = 0; i < summaryInfoList.Count; i++) {
var summaryInfo = summaryInfoList[i];
var groupSummaryCall = GetGroupSummaryCall(summaryInfo, group);
dictItems.Add(Expression.ElementInit(addMethod, Expression.Constant("Summary_" + i),
Expression.Convert(groupSummaryCall, typeof(object))));
}
var dictInit = Expression.ListInit(Expression.New(typeof(Dictionary<string, object>)), dictItems);
// creating the select query
Type selectFuncType = typeof(Func<,>).MakeGenericType(groupType, typeof(Dictionary<string, object>));
var selectLambda = Expression.Lambda(selectFuncType, dictInit, group);
var selectCall = Expression.Call(typeof(Queryable), "Select",
new[] { groupedQuery.ElementType, typeof(Dictionary<string, object>) },
groupedQuery.Expression, selectLambda);
return groupedQuery.Provider.CreateQuery<Dictionary<string, object>>(selectCall);
}
private static Expression GetGroupSummaryCall(GridCustomDataSourceSummaryInfo summaryInfo,
Expression group) {
var parameter = Expression.Parameter(typeof(Order));
var property = Expression.Property(parameter, summaryInfo.FieldName);
var summaryLambda = Expression.Lambda(property, parameter);
switch (summaryInfo.SummaryType) {
case GridSummaryItemType.Avg:
return Expression.Call(typeof(Enumerable), "Average", new[] { typeof(Order) },
group, summaryLambda);
case GridSummaryItemType.Count:
return Expression.Call(typeof(Enumerable), "Count", new[] { typeof(Order) },
group);
case GridSummaryItemType.Max:
return Expression.Call(typeof(Enumerable), "Max", new[] { typeof(Order), property.Type },
group, summaryLambda);
case GridSummaryItemType.Min:
return Expression.Call(typeof(Enumerable), "Min", new[] { typeof(Order), property.Type },
group, summaryLambda);
case GridSummaryItemType.Sum:
return Expression.Call(typeof(Enumerable), "Sum", new[] { typeof(Order) },
group, summaryLambda);
default:
throw new NotSupportedException(summaryInfo.SummaryType.ToString());
}
}
// ...
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (!_disposed) {
if (disposing) {
_context?.Dispose();
}
_disposed = true;
}
}
// ...
}
Related GitHub Examples
The following code snippet (auto-collected from DevExpress Examples) contains a reference to the SummaryType property.
Note
The algorithm used to collect these code examples remains a work in progress. Accordingly, the links and snippets below may produce inaccurate results. If you encounter an issue with code examples below, please use the feedback form on this page to report the issue.