Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linq select sum and average into view model

How can I do this in a single select statement?

var data = new CampaignData()
{
    TotalPost = await context.Campaigns.SumAsync(c => c.Posts),
    AveragePost = await context.Campaigns.AverageAsync(c => c.Posts),
    TotalImpression = await context.Campaigns.SumAsync(c => c.Impressions),
    AverageImpressions = await context.Campaigns.AverageAsync(c => c.Impressions),
};
like image 982
MIKE Avatar asked Dec 05 '25 11:12

MIKE


1 Answers

You can group by a constant so you can get the sums and averages. Then use SingleAsync to get the single result.

var data = await (from compaign in context.Compaigns
                  group compaign by 1 into grp
                  select new CampaignData()
                  {
                      TotalPost = grp.Sum(cc => cc.Posts),
                      AveragePost = grp.Average(c => c.Posts),
                      TotalImpression = grp.Sum(c => c.Impressions),
                      AverageImpressions = grp.Average(c => c.Impressions),
                  }).SingleAsync();

Another option is to actually let your asynchronous DB calls run in parallel

var totalPostTask = context.Campaigns.SumAsync(c => c.Posts);
var averagePostTask = context.Campaigns.AverageAsync(c => c.Posts);
var totalImpressionTask = context.Campaigns.SumAsync(c => c.Impressions);
var averageImpressionsTask = context.Campaigns.AverageAsync(c => c.Impressions);

await Task.WhenAll(
    totalPostTask, 
    averagePostTask, 
    totalImpressionTask, 
    averageImpressionsTask);

var data = new CampaignData()
{
    TotalPost = totalPostTask.Result,
    AveragePost = averagePostTask.Result,
    TotalImpression = totalImpressionTask.Result,
    AverageImpressions = averageImpressionsTask.Result,
};

If I had to guess I'd say the single DB call would perform better, but you can always test both options out to see which is better.

like image 120
juharr Avatar answered Dec 06 '25 23:12

juharr