제품 컬렉션이 있습니다
public class Product {
public Product() { }
public string ProductCode {get; set;}
public decimal Price {get; set; }
public string Name {get; set;}
}
이제 제품 코드를 기준으로 컬렉션을 그룹화하고 이름, 각 코드의 제품 또는 각 제품의 총 가격이 포함 된 개체를 반환하려고합니다.
public class ResultLine{
public ResultLine() { }
public string ProductName {get; set;}
public string Price {get; set; }
public string Quantity {get; set;}
}
그래서 GroupBy를 사용하여 ProductCode별로 그룹화 한 다음 합계를 계산하고 각 제품 코드의 레코드 수를 계산합니다.
이것이 내가 지금까지 가진 것입니다.
List<Product> Lines = LoadProducts();
List<ResultLine> result = Lines
.GroupBy(l => l.ProductCode)
.SelectMany(cl => cl.Select(
csLine => new ResultLine
{
ProductName =csLine.Name,
Quantity = cl.Count().ToString(),
Price = cl.Sum(c => c.Price).ToString(),
})).ToList<ResultLine>();
어떤 이유로 합계는 올바르게 수행되지만 카운트는 항상 1입니다.
삼페 데이터 :
List<CartLine> Lines = new List<CartLine>();
Lines.Add(new CartLine() { ProductCode = "p1", Price = 6.5M, Name = "Product1" });
Lines.Add(new CartLine() { ProductCode = "p1", Price = 6.5M, Name = "Product1" });
Lines.Add(new CartLine() { ProductCode = "p2", Price = 12M, Name = "Product2" });
샘플 데이터 결과 :
Product1: count 1 - Price:13 (2x6.5)
Product2: count 1 - Price:12 (1x12)
제품 1은 개수 = 2 여야합니다!
간단한 콘솔 응용 프로그램에서 이것을 시뮬레이션하려고 시도했지만 다음과 같은 결과가 나타납니다.
Product1: count 2 - Price:13 (2x6.5)
Product1: count 2 - Price:13 (2x6.5)
Product2: count 1 - Price:12 (1x12)
Product1 : 한 번만 나열해야합니다 … 위의 코드는 pastebin에서 찾을 수 있습니다. http://pastebin.com/cNHTBSie
답변
첫 번째 “샘플 데이터 결과”가 어디에서 오는지 이해하지 못하지만 콘솔 앱의 문제 는 각 그룹의 각 항목SelectMany
을 보는 데 사용 한다는 것 입니다.
난 당신이 원하는 것 같아요 :
List<ResultLine> result = Lines
.GroupBy(l => l.ProductCode)
.Select(cl => new ResultLine
{
ProductName = cl.First().Name,
Quantity = cl.Count().ToString(),
Price = cl.Sum(c => c.Price).ToString(),
}).ToList();
사용 First()
제품 이름을 얻기 위해 여기에 같은 제품 코드와 모든 제품이 동일한 제품 이름이 있다고 가정합니다. 주석에서 언급했듯이 제품 코드뿐만 아니라 제품 이름별로 그룹화 할 수 있습니다. 이는 주어진 코드에서 이름이 항상 동일하지만 EF에서 더 나은 SQL을 생성하는 경우 동일한 결과를 제공합니다.
또한 Quantity
및 Price
속성을 각각 int
및 decimal
유형으로 변경해야한다고 제안합니다. 텍스트가 아닌 데이터에 대해 문자열 속성을 사용하는 이유는 무엇입니까?
답변
다음 쿼리가 작동합니다. 대신 각 그룹을 사용하여 선택을 수행합니다 SelectMany
. SelectMany
각 컬렉션의 각 요소에서 작동합니다. 예를 들어 쿼리에서 2 개의 컬렉션 결과가 있습니다. SelectMany
각 컬렉션 대신 총 3 개의 모든 결과를 가져옵니다. 다음 코드 IGrouping
는 선택 부분 에서 각각 작동 하여 집계 작업이 올바르게 작동하도록합니다.
var results = from line in Lines
group line by line.ProductCode into g
select new ResultLine {
ProductName = g.First().Name,
Price = g.Sum(pc => pc.Price).ToString(),
Quantity = g.Count().ToString(),
};
답변
때로는 일부 필드를 선택 FirstOrDefault()
하거나 singleOrDefault()
아래 쿼리를 사용할 수 있습니다.
List<ResultLine> result = Lines
.GroupBy(l => l.ProductCode)
.Select(cl => new Models.ResultLine
{
ProductName = cl.select(x=>x.Name).FirstOrDefault(),
Quantity = cl.Count().ToString(),
Price = cl.Sum(c => c.Price).ToString(),
}).ToList();