2012-01-24 63 views
8

Tôi muốn nhóm truy vấn LINQ của mình theo số ItemNumber và trả lại toàn bộ bảng với tổng số là Quantity.Biểu thức Lambda Nhóm theo trong C#

Example: 
ItemNumber - ItemName - Quantity 
100   Item1  1 
150   Item2  2 
100   Item1  2 
200   Item3  1 
150   Item2  2 

Should be: 
ItemNumber - ItemName - Quantity 
100   Item1  3 
150   Item2  4 
200   Item3  1 

Đây là truy vấn Tôi cố gắng để nhóm:

public IQueryable<WebsiteOrderStatus> GetOrderStatusByAccountNumberWithoutDeleted 
     (string accountNumber) 
{ 
    return db.WebsiteOrderStatus 
      .Where(x => x.AccountNumber == accountNumber && x.LastUpdatedStatus != 1); 
} 

Và kết quả tốt nhất của tôi cho đến nay (điều này không thể biên dịch mặc dù):

public IQueryable<IGrouping<Int32?, WebsiteOrderStatus>> lol(string accountNumber) 
{ 
    db.WebsiteOrderStatus 
     .Where(x => x.AccountNumber == accountNumber && x.LastUpdatedStatus != 1) 
     .GroupBy(g => g.ItemNumber) 
     .Select(g => new 
        { 
         g.Key.ItemNumber, 
         Column1 = (Int32?)g.Sum(p => p.Quantity) 
        }); 
} 

EDIT:

Cảm ơn bạn đã trả lời tất cả mọi người, tôi phải đối mặt với nó. Các loại vô danh của người Theese khá khó làm việc theo ý kiến ​​của tôi, vì vậy tôi đã tìm ra một giải pháp khác.

Tôi đã thực hiện một phương pháp khác, tính tổng số lượng các mục của người dùng và nhóm số lượng đầu tiên.

public IQueryable<WebsiteOrderStatus> GetOrderStatusByAccountNumberWithoutDeleted(string accountNumber) 
{ 
    return db.WebsiteOrderStatus.Where(x => x.AccountNumber == accountNumber && x.LastUpdatedStatus != 1).GroupBy(x => x.ItemNumber).Select(grp => grp.First()); 
} 

public int GetQuantityOfUsersItem(string accountNumber, string itemNumber) 
{ 
    return db.WebsiteOrderStatus.Where(x => x.ItemNumber == itemNumber && x.AccountNumber == accountNumber).Sum(x => x.Quantity); 
} 

Tại trang mà tôi có GridView của tôi, tôi đã làm:

var query = websiteOrderStatusRep.GetOrderStatusByAccountNumberWithoutDeleted(AppSession.CurrentLoginTicket.AccountNumber).Select(x => new { x.ItemName, x.ItemNumber, x.FormatName, x.Price, x.Status, x.Levering, Quantity = websiteOrderStatusRep.GetQuantityOfUsersItem(x.AccountNumber, x.ItemNumber)}); 
+1

Không chắc những gì khác là sai, nhưng ít nhất, bạn' lại thiếu một 'return' trong mẫu thứ hai. – Ani

+0

Lỗi biên dịch bạn đang nhận được là gì? –

+1

Có lẽ anh ấy đang cố coi g.Key là một đối tượng, trong khi đó chỉ là int. Nếu anh ta muốn tên mục trong kết quả thì anh ta cũng sẽ phải lưu nó trong đối tượng chính (và làm cho các phím trở thành một đối tượng có thể so sánh được) hoặc đọc nó từ mục nhập đầu tiên trong nhóm enumberator mà tôi đoán. – Rup

Trả lời

10
public IQueryable<IGrouping<Int32?, WebsiteOrderStatus>> lol(string accountNumber) 
{ 
    db.WebsiteOrderStatus 
     .Where(x => x.AccountNumber == accountNumber && x.LastUpdatedStatus != 1) 
     .GroupBy(g => g.ItemNumber) 
     .Select(g => new 
        { 
         ItemNumber = g.Key, 
         ItemName = g.First().ItemName, 
         Count = g.Sum(item => item.Quantity) 
        }); 
} 
3

Tôi nghĩ rằng Select nên là:

.Select(g => new 
       { 
        ItemNumber = g.Key, 
        Column1 = (Int32?)g.Sum(p => p.Quantity) 
       }); 

Lưu ý sự thay đổi trong dòng đầu tiên của loại ẩn danh. Khóa của nhóm đã là số mục.

5

Những vấn đề duy nhất tôi thấy với truy vấn của bạn được

  1. Thiếu return tuyên bố như một cảm
  2. Các lựa chọn công bố nên là:

-

.Select(g => new { 
     ItemNumber = g.Key, 
     Total = g.Sum(p => p.Quantity) 
    }); 

EDIT: Nếu bạn muốn nhận được, cho phép nói ItemNumber và ITEMNAME, trong đối tượng kết quả, bạn cũng phải nhóm trên những lĩnh vực

db.WebsiteOrderStatus 
    .Where(x => x.AccountNumber == accountNumber && x.LastUpdatedStatus != 1) 
    .GroupBy(g => new { g.ItemNumber, g.ItemName }) 
    .Select(g => new 
       { 
        ItemNumber = g.Key.ItemNumber, 
        ItemName = g.Key.ItemName, 
        Count = g.Sum(item => item.Quantity) 
       }); 
+0

Có vẻ như nó chỉ trả về ItemNumber và Total rồi. Những gì tôi muốn là toàn bộ bảng chỉ với một cột có tên là tổng, trong đó có tổng số cho số lượng – KLIM8D

+0

@ KLIM8D - Xem cập nhật – Jamiec

+0

okay, soo mọi đối tượng tôi muốn nhận được trong kết quả phải ở trong nhóm. Tôi thực sự có 5 lĩnh vực khác trong bảng, có thể có một cách tốt hơn làm nhóm này khác hơn tất cả các lĩnh vực tôi cần phải được chứa trong groupby? – KLIM8D

7
public IQueryable<OrderStatus > lol(string accountNumber) 
{ 
    return db.WebsiteOrderStatus 
     .Where(x => x.AccountNumber == accountNumber && x.LastUpdatedStatus != 1) 
     .GroupBy(g => g.ItemNumber) 
     .Select(g => 
       new OrderStatus //This is your custom class, for binding only 
       { 
        ItemNumber = g.Key, 
        ItemName = g.First().ItemName, 
        Quantity = g.Sum(g => g.Quantity) 
       } 
     ); 
} 
+0

Chúng ta gần như ở đó - không có lỗi cho đến khi tôi cố gắng ràng buộc truy vấn của tôi vào chế độ xem lưới. Tôi nhận ngoại lệ này: System.NotSupportedException: Việc xây dựng rõ ràng loại đối tượng 'GWportal.BusinessLayer.Repository.WebsiteOrderStatus' trong truy vấn không được phép. – KLIM8D

+2

'Các thực thể có thể được tạo bên ngoài các truy vấn và được chèn vào kho dữ liệu bằng cách sử dụng một DataContext. Sau đó, bạn có thể truy xuất chúng bằng truy vấn. Tuy nhiên, bạn không thể tạo các thực thể như là một phần của truy vấn.' Trong trường hợp này, bạn sẽ phải tạo một lớp tùy chỉnh để gắn kết và ánh xạ 'WebsiteOrderStatus' với đối tượng của lớp đó. –

2

Bạn không thể sử dụng loại vô danh cho loại giá trị trả về. Vì vậy, bạn sẽ không bao giờ biên dịch mã.

Ngoài ra biểu thức LINQ của bạn có IQueryable < [loại ẩn danh]> loại kết quả.

Tôi tin rằng bạn có thể làm một cái gì đó như thế này:

public IQueryable<OrderStatus> lol(string accountNumber) 
{ 
    db.WebsiteOrderStatus 
     .Where(order => order.AccountNumber == accountNumber && order.LastUpdatedStatus != 1) 
     .GroupBy(order => order.ItemNumber) 
     .Select(grouping => new OrderStatus //This is your custom class, for binding only 
        { 
         ItemNumber = grouping.Key, 
         ItemName = grouping.First().ItemName, 
         Quantity = grouping.Sum(order => order.Quantity) 
        }); 
} 

`ve cố định câu trả lời của tôi quá :)

+0

Tại sao bạn không thể sử dụng các loại ẩn danh làm giá trị trả lại. – Jamiec

+1

Làm thế nào bạn xác định nó trong chữ ký của phương pháp? –

+0

MSDN: Bạn không thể khai báo trường, thuộc tính, sự kiện hoặc loại trả về của phương thức có loại ẩn danh. Tương tự, bạn không thể khai báo một tham số chính thức của một phương thức, thuộc tính, hàm tạo hoặc trình chỉ mục như có một kiểu ẩn danh. Để truyền một loại vô danh, hoặc một bộ sưu tập chứa các kiểu vô danh, làm đối số cho một phương thức, bạn có thể khai báo tham số đó làm đối tượng kiểu. Tuy nhiên, làm điều này đánh bại mục đích gõ mạnh mẽ. Nếu bạn phải lưu trữ các kết quả truy vấn hoặc vượt qua chúng bên ngoài ranh giới phương thức, hãy xem xét sử dụng một cấu trúc hoặc lớp được đặt tên thông thường thay vì một kiểu ẩn danh. –