Reputation: 23
I'm trying to produce a data set for a graph that would get me the same result as the following SQL query:
select
concat(year(InvoiceDate), '-', month(PaymentDate)) as Period,
sum(InvoiceTable.InvoiceAmount) as BilledAmount,
-sum(AccountTable.Payment) as IncomingPayments,
from InvoiceTable
left join AccountTable on InvoiceTable.InvoiceID = AccountTable.InvoiceID
where InvoiceTable.InvoiceDate >= cast('2019/01/01' as date) and InvoiceTable.InvoiceDate < cast('2020/01/01' as date)
group by concat(year(InvoiceDate), '-', month(PaymentDate))
But if I try to translate it into a linq query, I can't get the same result, I either don't have access to one or the other side of the junction, or I get a yearly total of one or the other side.
var data = from a in db.InvoiceTable
where a.InvoiceDate >= FiscalYear.StartDate && a.InvoiceDate <= FiscalYear.EndDate
join b in db.AccountTable on a.InvoiceID equals b.InvoiceID into ab
from c in ab.DefaultIfEmpty()
let period = string.Concat(a.InvoiceDate.Year, "-", a.InvoiceDate.Month)
group a by period into g
select new
{
Period = g.Key,
Billed = g.Sum(o => o.InvoiceAmount),
Collected = -b.Sum(o => (decimal?)o.Payment) ?? 0m //Can't access the right side anymore and if I group c I can't access the left side then
};
I tried to nest another linq query in the Collected
column but then I would get the yearly amount on each month (g.Key
).
Upvotes: 1
Views: 61
Reputation: 27416
This query should work. You have to include into grouping more items. Also I have optimized your query do group by two fields, not a concatenation.
var data = from a in db.InvoiceTable
where a.InvoiceDate >= FiscalYear.StartDate && a.InvoiceDate <= FiscalYear.EndDate
join b in db.AccountTable on a.InvoiceID equals b.InvoiceID into ab
from b in ab.DefaultIfEmpty()
group new { a, b } by new { a.InvoiceDate.Year, a.InvoiceDate.Month } into g
select new
{
Period = g.Key.Year + "-" + g.Key.Month,
Billed = g.Sum(o => o.a.InvoiceAmount),
Collected = -b.Sum(o => (decimal?)o.b.Payment)
};
Upvotes: 1