I'm fairly new to EF Core, so please forgive me if I'm missing something easy here or went about this the wrong way. I have the following models (I have removed irrelevant relationships / data for brevity):
public class SaleOrder
{
public int SaleOrderId { get; set; }
public ICollection<SaleOrderRule> Rules { get; set; }
public ICollection<Carton> ScannedCartons { get; set; }
}
public class SaleOrderRule
{
public int SaleOrderRuleId { get; set; }
public int SaleOrderId { get; set; }
public SaleOrder SaleOrder { get; set; }
public int ProductCodeId { get; set; }
public ProductCode ProductCode { get; set; }
public int Quantity { get; set; }
}
public class ProductCode
{
public int ProductCodeId { get; set; }
public string Value { get; set; }
}
public class Carton
{
public int CartonId { get; set; }
public string BoxID { get; set; }
public int ProductCodeId { get; set; }
public ProductCode ProductCode { get; set; }
public int? SaleOrderId { get; set; }
public SaleOrder? SaleOrder { get; set; }
}
A Product Code and Quantity make up a rule, and a Sale Order can have many Rules and Cartons, Cartons can only be added to the Sales Order if the Product Code matches one of the rules, I am trying to query a breakdown of the data for a single Sale Order, including:
- The SaleOrderRuleId
- The Product Code
- The Total Cartons scanned for this Rule
- The Total Quantity required for this Rule And
- A list of the Scanned Cartons for the rule (just the BoxID and CartonId)
I came up with the following query:
var saleOrderCartonCountBreakdown = await
(from c in _context.Cartons
where c.SaleOrderId == id
group c by new
{
c.ProductCodeId,
} into g
select new
{
ProductCodeId = g.Key.ProductCodeId,
CartonInfo = g.Select(x =>
new SaleOrderCartonBreakdownCarton {
CartonId = x.CartonId,
BoxID = x.BoxID
}).ToList(),
Count = g.Count()
} into gv
join pc in _context.ProductCodes on gv.ProductCodeId equals pc.ProductCodeId
join sor in _context.SaleOrderRules on gv.ProductCodeId equals sor.ProductCodeId
select new SaleOrderCartonBreakdownModel
{
SaleOrderRuleId = sor.SaleOrderRuleId,
ProductCode = pc.Value,
TotalScanned = gv.Count,
TotalRequired = sor.Quantity,
CartonList = gv.CartonInfo.ToList()
}).ToListAsync();
This works, but it only includes data if there is atleast one scanned carton for a product code, the intention is to also include the product codes for rules which do not have any cartons scanned in yet.
I'm fairly certain this is because I am starting on the Cartons table, however my attempts to rewrite the query to start on the SaleOrderRules and output the same result have been unsuccessful.
Any help is much appreciated :)