public override object Eval(DataRow row) { //TODO: implement a better caching strategy and a mechanism for cache invalidation. //for now only aggregation over the table owning 'row' (e.g. 'sum(parts)' //in constrast to 'sum(child.parts)') is cached. if (cacheResults && result != null && column.ReferencedTable == ReferencedTable.Self) { return(result); } count = 0; result = null; object[] values; if (rows == null) { values = column.GetValues(column.GetReferencedRows(row)); } else { values = column.GetValues(rows); } foreach (object val in values) { if (val == null) { continue; } count++; Aggregate((IConvertible)val); } switch (function) { case AggregationFunction.StDev: case AggregationFunction.Var: result = CalcStatisticalFunction(values); break; case AggregationFunction.Avg: result = ((count == 0) ? DBNull.Value : Numeric.Divide(result, count)); break; case AggregationFunction.Count: result = count; break; } if (result == null) { result = DBNull.Value; } if (cacheResults && column.ReferencedTable == ReferencedTable.Self) { table = row.Table; row.Table.RowChanged += RowChangeHandler; } return(result); }