I have a list that is being populated with the summed quantities of specific product ID's, for example:
My table:
My program checks for a user input and then compares that user input to the Quantity column in the table - once a match is found, the program checks for the ProductID of the matched quantity, and then adds ALL the quantities relating to that matched ProductID.
For example, if a user enters 2, the program will check for all the values in the Quantity column greater than or equal to 2 - so in this case, the first row to be found would be row 2 (which has a productID of 9 and a quantity of 2). The program should now search for ALL productID's equal to 9 and then sum their individual quantities (which will be 3 in this case, as the ProductID 9 appears only twice, with the quantities 2 and 1 respectively), and then save that final summed quantity (3) into the list. And then the program should continue to row 3 (which has a productID of 8 and a quantity of 3). The program should now search for ALL productID's equal to 8 and then sum their individual quantities (which will be 9 in this case, as the ProductID 8 appears three times, with the quantities 3 and 3 and 3 respectively), and then save that final summed quantity (9) into the list. And then the program should SKIP row 4, because the ProductID of 9 has already been dealt with - and so on and so forth.
So far i have tried this:
var dynamicReader = DBAccessor.InvoiceLines.Where(xx => xx.Quantity >= quantitySelected).Select(yy => yy.ProductID);
foreach (var product in dynamicReader)
{
if (!quantityArrayList.Contains(product))
{
quantityArrayList.Add(DBAccessor.InvoiceLines.Where(gg => gg.ProductID == product).Sum(g => g.Quantity));
}
}
If the user enters 2, the first 4 results using this method are correct, however, after that, the summed values fetched make little sense to me. Any help on this matter would be greatly appreciated.
It looks like you're not associating the ProductID
with the Quantity
stored in quantityArrayList
. So, when you check quantityArrayList.Contains(product)
you're not checking to see if that ProductID
has already been processed, you're checking to see if there is a sum of quantities which match the ProductID
.
I don't know what type quantityArrayList
is, I'm assuming it's a List<int>
. Instead, you should use a Dictionary
where the key would be the ProductID
and the value would be the sum of the Quantity
.
Untested, but the updated code might look like...
Dictionary<int, int> productQuantities = new Dictionary<int, int>(); //I've changed the name, but this would replace quantityArrayList
var dynamicReader = DBAccessor.InvoiceLines.Where(xx => xx.Quantity >= quantitySelected).Select(yy => yy.ProductID);
foreach (var product in dynamicReader)
{
if (!productQuantities.ContainsKey(product))
{
productQuantities.Add(product, DBAccessor.InvoiceLines.Where(gg => gg.ProductID == product).Sum(g => g.Quantity));
}
}
I would use GroupBy
with 2 values mapped to the grouping: Max
and Sum
. If the max quantity of one of the entries is greater than your desired amount, that grouping is 'in scope' and you want to get its sum. Like this:
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
var productCounts = new List<ProductCount>{
new ProductCount{ProductId = 10, Quantity = 1},
new ProductCount{ProductId = 9, Quantity = 2},
new ProductCount{ProductId = 8, Quantity = 3},
new ProductCount{ProductId = 9, Quantity = 1},
new ProductCount{ProductId = 7, Quantity = 2},
new ProductCount{ProductId = 5, Quantity = 3},
new ProductCount{ProductId = 8, Quantity = 3},
new ProductCount{ProductId = 6, Quantity = 2}
};
var desiredMinimum = 3;
var output = productCounts.GroupBy(i => i.ProductId)
.Select(i => new
{
ProductId = i.Key,
Max = i.Max(j => j.Quantity),
Total = i.Sum(j => j.Quantity)
})
.Where(i => i.Max >= desiredMinimum)
.ToList();
foreach(var outputItem in output){
Console.WriteLine("ProductId: " + outputItem.ProductId + "; Total: " + outputItem.Total);
}
}
internal class ProductCount
{
public int ProductId{get;set;}
public int Quantity{get;set;}
}
}
See:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.