2013-04-19 37 views
21

Tôi muốn thực hiện truy vấn với LINQ (danh sách đối tượng) và tôi thực sự không biết cách thực hiện, tôi có thể thực hiện nhóm và tổng nhưng không thể chọn phần còn lại của nhữn cánh đồng. Ví dụ:Chọn nhiều trường theo và tổng số

ID Value  Name Category 
1 5   Name1 Category1 
1 7   Name1 Category1 
2 1   Name2 Category2 
3 6   Name3 Category3 
3 2   Name3 Category3 

Tôi muốn nhóm theo ID, SUM theo giá trị và trả về tất cả các trường như thế này.

ID Value  Name Category 
1 12  Name1 Category1 
2 1   Name2 Category2 
3 8   Name3 Category3 
+0

Bạn có kiểm tra không? http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b và trường hợp của bạn: http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b – Aristos

+0

vì tất cả các trường có vẻ là duy nhất cho mỗi ID, tại sao bạn cũng không bao gồm chúng trong nhóm. – Habib

+0

Có, tôi có thể làm điều đó nhưng tôi có nhiều trường hơn thế ... :( – user2112420

Trả lời

44

Cập nhật: Nếu bạn đang cố gắng để tránh nhóm cho tất cả các lĩnh vực, bạn có thể nhóm chỉ bằng Id:

data.GroupBy(d => d.Id) 
    .Select(
     g => new 
     { 
      Key = g.Key, 
      Value = g.Sum(s => s.Value), 
      Name = g.First().Name, 
      Category = g.First().Category 
     }); 

Nhưng mã này giả định rằng đối với mỗi Id, cùng một số NameCategory áp dụng. Nếu vậy, bạn nên xem xét bình thường hóa như @Aron gợi ý. Nó sẽ ngụ ý giữ IdValue trong một lớp và di chuyển Name, Category (và bất kỳ trường nào khác sẽ giống nhau cho cùng một Id) đến một lớp khác, trong khi cũng có Id để tham khảo. Quá trình bình thường hóa làm giảm sự dư thừa dữ liệu và sự phụ thuộc.

+0

Có, tôi biết điều đó nhưng chỉ không muốn nhóm tất cả các lĩnh vực, sẽ là một cách differnt, tôi cố gắng với đầu tiên() nhưng sau đó làm thế nào để tổng hợp? – user2112420

+0

Tôi đã cập nhật câu trả lời. –

+0

Có tôi biết bạn đang nói gì, tôi có DB bình thường hóa, nó chỉ là kết quả của truy vấn của tôi, nhưng đối với mỗi dòng truy vấn của tôi, tôi đã lặp lại giá trị, và tôi muốn gộp chúng lại và tổng giá trị. – user2112420

2
void Main() 
{ 
      //Me being lazy in init 
    var foos = new [] 
    { 
     new Foo { Id = 1, Value = 5}, 
     new Foo { Id = 1, Value = 7}, 
     new Foo { Id = 2, Value = 1}, 
     new Foo { Id = 3, Value = 6}, 
     new Foo { Id = 3, Value = 2}, 
    }; 
    foreach(var x in foos) 
    { 
     x.Name = "Name" + x.Id; 
     x.Category = "Category" + x.Id; 
    } 
      //end init. 

    var result = from x in foos 
       group x.Value by new { x.Id, x.Name, x.Category} 
       into g 
       select new { g.Key.Id, g.Key.Name, g.Key.Category, Value = g.Sum()}; 
    Console.WriteLine(result); 
} 

// Define other methods and classes here 
public class Foo 
{ 
    public int Id {get;set;} 
    public int Value {get;set;} 

    public string Name {get;set;} 
    public string Category {get;set;} 
} 
+0

Tôi biết theo cách này, nhưng tôi không muốn có trong nhóm của tôi rất nhiều lĩnh vực, tôi có nhiều hơn rằng 7. – user2112420

+0

@ user2112420 Sau đó, bạn sẽ phải bình thường hóa lớp học của bạn – Aron

+0

Đó là một truy vấn kết quả tôi – user2112420

1

thử điều này:

var objList = new List<SampleObject>(); 

objList.Add(new SampleObject() { ID = 1, Value = 5, Name = "Name1", Category = "Catergory1"}); 
objList.Add(new SampleObject() { ID = 1, Value = 7, Name = "Name1", Category = "Catergory1"}); 
objList.Add(new SampleObject() { ID = 2, Value = 1, Name = "Name2", Category = "Catergory2"}); 
objList.Add(new SampleObject() { ID = 3, Value = 6, Name = "Name3", Category = "Catergory3"}); 
objList.Add(new SampleObject() { ID = 3, Value = 2, Name = "Name3", Category = "Catergory3"}); 

var newList = from val in objList 
       group val by new { val.ID, val.Name, val.Category } into grouped 
       select new SampleObject() { ID = grouped.ID, Value = grouped.Sum(), Name = grouped.Name, Category = grouped.Category }; 

để kiểm tra với LINQPad:

newList.Dump(); 
Các vấn đề liên quan