entity framework - How can I achieve to implement the below query without the if statement (SUM/AVG)? -
public class dailyaggregator : aggregator { public override dictionary<string, int?> aggregate<t>(iqueryable<t> query, expression<func<t, datetime>> groupbyproperty, expression<func<t, double>> operationproperty = null) { if (operationproperty == null) // property of sum/avg (null = count) operationproperty = x => 1; if (_operationtype.equals(reportaggregationoperation.sum)) { return query .groupby(g => new { day = testabledbfunctions.truncatetime(groupbyproperty.invoke(g)) }) .select(x => new { key = x.key.day.tostring().substring(0, 10), value = (int?) x.sum(operationproperty.compile()), }) .todictionary(t => t.key, t => t.value); } else { return query .groupby(g => new { day = dbfunctions.truncatetime(groupbyproperty.invoke(g)) }) .select( x => new { key = x.key.day.tostring().substring(0, 10), value = (int?) x.average(operationproperty.compile()), }).todictionary(t => t.key, t => t.value); } } }
i'm using ioc container creating instances dailyaggreagtor/monthlyaggregator... wasn't able build group expression, or apply right design pattern eliminate above if statement.
the compile , invoke functions comes linqkit extension. classes using aggregator(s) querying db , collecting data callcenter reports (ex. totalcdrrecords report, reachedcdrrecords report, cdrtalktime report, cdrcallafterworktime etc., cdr call data record, practically holding information call). type of query (t) specified in report classes, ireportableentity, of course operationproperty can property of db entity can perfom count/sum/avg operations, groupbyproperty datetime column.
it generates following sql query:
select 1 [c1], substring(case when ([groupby1].[k1] null) n'' else cast( [groupby1].[k1] nvarchar(max)) end, 0 + 1, 10) [c2], cast( [groupby1].[a1] int) [c3] ( select [filter1].[k1] [k1], sum([filter1].[a1]) [a1] ( select convert (datetime2, convert(varchar(255), [extent1].[createdon], 102) , 102) [k1], cast(1 float(53)) [a1] [dbo].[vcccdr] [extent1] ([extent1].[createdon] >= @p__linq__0) , ([extent1].[createdon] <= @p__linq__1) , ([extent1].[companyid] = @p__linq__2) ) [filter1] group [k1] ) [groupby1]
since using linqkit, can extract expression calling sum
/ average
part , invoke
inside query.
for instance:
var aggregatefunc = _operationtype.equals(reportaggregationoperation.sum) ? linq.expr((ienumerable<double> source) => source.sum()) : linq.expr((ienumerable<double> source) => source.average()); return query .groupby(g => new { day = dbfunctions.truncatetime(groupbyproperty.invoke(g)) }) .select(x => new { key = x.key.day.tostring().substring(0, 10), value = (int?)aggregatefunc.invoke(x.select(operationproperty.compile())), }) .todictionary(t => t.key, t => t.value);
Comments
Post a Comment