I have a legacy .net application where certain code is trying to sum up the counts for certain related database rows. It's an inventory solution where items could be added to the system from multiple sources (item receipts, adjustments, returns, etc).
The current code isn't very performant due mostly to it executing multiple queries, one for each relationship and adding them to a running counter. This is in code on the main item class so it is making use of the relationship attributes to start each line
count += ReceiptLines.Where(p => p.ItemReceipt.TxnDate < dt).Sum(p => p.Quantity);
count += AdjustmentLines.Where(p => p.Adjustment.TxnDate < dt).Sum(p => p.Quantity);
count += TransferLines.Where(p => p.Transfer.TxnDate < dt).Sum(p => p.Quantity);
count += ReturnLines.Where(p => p.Return.TxnDate < dt).Sum(p => p.Quantity);
This is just a snippet as the code has many more inputs and some lines that reduce the count. There are usually ~14 different queries just to calculate this one value.
I was hoping that if I could move all of this to one query it would make the method more performant, but I'm rather new to .NET and LINQ and I'm unsure how to combine these into a single query.
Is there an approach with LINQ that would allow me to merge these statements?
Edit to answer question below:
This is how these attributes are defined on the Item class (where the code above lives)
[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Item_ReturnLine", Storage="_ReturnLines", ThisKey="ItemId", OtherKey="ItemId")]
public EntitySet<ReturnLine> ReturnLines ...
These are the mappings to the tables like ReceiptLines that make reference to this Item object.
2nd Edit
I did some DB work and the query example below is pretty close to what this should be (with a few tweaks).
select i.itemid as itemId
, ISNULL(irl.total, 0) + ISNULL( rl.total, 0) + ISNULL(ial.total, 0) + ISNULL( itl.total, 0) as total,
CacheQuantityOnHand
from item i
left join ( select itemid, sum(quantity) as total from ItemReceiptLine where TxnDate < SYSDATETIME() group by itemid) irl on i.itemid = irl.itemid
left join ( select itemid, sum(quantity) as total from ReturnLine where TxnDate < SYSDATETIME() group by itemid) rl on i.itemid = rl.itemid
left join ( select itemid, sum(QuantityDiff) as total from InventoryAdjustmentLine where TxnDate < SYSDATETIME() group by itemid) ial on i.itemid = ial.itemid
left join ( select itemid, sum(quantity) as total from InventoryTransferLine where TxnDate < SYSDATETIME() group by itemid) itl on i.itemid = itl.itemid
This seems pretty fast from my testing, but I'm not sure still how to implement this in LINQ