1

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 :)

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Watto
  • 21
  • 1
  • Hi @Watto, it seems what you want is full outer join, right? I suggest you can refer to this answer here: https://stackoverflow.com/a/5491381/11398810 – Rena Aug 25 '22 at 09:17

0 Answers0