Reputation: 7542
Example query:
var results = await campaignList
.GroupBy(x => x.Campaign)
.Select(c => new ReportModel
{
CampaignId = c.Key.Id,
CoregName = c.Key.Name,
TotalVisitors = startDate == null || endDate == null ? c.Key.LogPixelCalls.Count : c.Key.LogPixelCalls.Count(x => x.CreatedOn >= startDate && x.CreatedOn <= endDate),
TotalUsers = c.Count(),
TotalPaidUsers = c.Count(x => x.UserSignature.StripeCustomerId != null),
TotalUserConversion = !c.Any() || c.Key.LogPixelCalls.Count == 0 ? 0 : (decimal)c.Count() / (decimal)c.Key.LogPixelCalls.Count * 100,
TotalPaidUserConversion = c.Count(x => x.UserSignature.StripeCustomerId != null) == 0 || !c.Any() ? 0 : (decimal)c.Count(x => x.UserSignature.StripeCustomerId != null) / (decimal)c.Count() * 100
})
.OrderByDescending(c => c.TotalPaidUsers)
.ToListAsync();
It selects Campaigns which have data connected with corresponding CampaignId. How to select all Campaigns and if there is no data in other tables, fill 0 values in .Select ?
Example: Campaign 1, 44, 22, 33 Campaign 2, 0, 0, 0
Campaign 2 doesn't have any data, but I still want to show it in result.
Edit: Tried to use GroupJoin without success:
var resultinho = campaigns.GroupJoin(
results,
foo => foo.Id,
bar => bar.CampaignId,
(x, y) => new { Foo = x, Bar = y })
.SelectMany(
x => x.Bar.DefaultIfEmpty(),
(x, y) => new ReportModel
{
CampaignId = x.Bar.FirstOrDefault().CampaignId,
CoregName = x.Bar.FirstOrDefault().CoregName,
TotalVisitors = x.Bar.FirstOrDefault().TotalVisitors,
TotalUsers = x.Bar.FirstOrDefault().TotalUsers,
TotalPaidUsers = x.Bar.FirstOrDefault().TotalPaidUsers,
TotalUserConversion = x.Bar.FirstOrDefault().TotalUserConversion,
TotalPaidUserConversion = x.Bar.FirstOrDefault().TotalPaidUserConversion
})
.ToList();
Upvotes: 0
Views: 58
Reputation: 1101
group/sum campaign data first and left join the campaign with the grouped results
var cd = campaigns.GroupBy (c => new {c.ID} ).Select (cp =>
new {
cId= cp.Key.ID,
TotalUsers = cp.Count(),
TotalSum= cp.Sum( x=>x.UsersByCampaign)
...
} );
var results = campaignList.ForEach( cl => cd.Where( cdd => cdd.cId == cl.Id)
.Select(cdd => new { CampaignId = cdd.CId, TotalVisitors = cdd.TotalUsers , .. })
.DefaultIfEmpty( new { CampaignId = cdd.CId, TotalVisitors =0 , .. });
Upvotes: 1
Reputation: 7542
I did like this:
var resultsWithEmtpyCampaigns = campaigns.GroupJoin(
results,
camp => camp.Id,
campResult => campResult.CampaignId,
(x, y) => y.Select(c => new ReportModel
{
CampaignId = y.FirstOrDefault().CampaignId,
CoregName = y.FirstOrDefault().CoregName,
TotalVisitors = y.FirstOrDefault().TotalVisitors,
TotalUsers = y.FirstOrDefault().TotalUsers,
TotalPaidUsers = y.FirstOrDefault().TotalPaidUsers,
TotalUserConversion = y.FirstOrDefault().TotalUserConversion,
TotalPaidUserConversion = y.FirstOrDefault().TotalPaidUserConversion,
ReportCountryList = y.FirstOrDefault().ReportCountryList
})
.DefaultIfEmpty(new ReportModel
{
CampaignId = x.Id,
CoregName = x.Name,
TotalVisitors = 0,
TotalUsers = 0,
TotalPaidUsers = 0,
TotalUserConversion = 0,
TotalPaidUserConversion = 0
}))
.SelectMany(g => g).ToList();
return
resultsWithEmtpyCampaigns;
Upvotes: 1