2009-01-23 41 views
6

Nếu tôi có một bảng có cột tiêu đề và cột 3 bit (f1, f2, f3) có chứa 1 hoặc NULL, làm cách nào tôi viết LINQ để trả về tiêu đề với số lượng mỗi cột bit bit có chứa 1? Tôi đang tìm tương đương với truy vấn SQL này:LINQ COUNT trên nhiều cột

SELECT title, COUNT(f1), COUNT(f2), COUNT(f3) FROM myTable GROUP BY title 

Tôi đang tìm cách "tốt nhất" để thực hiện. Phiên bản tôi đã đưa ra dips vào bảng 4 lần khi bạn nhìn vào SQL cơ bản, vì vậy nó quá chậm.

Trả lời

0

Đây là giải pháp tôi đã đưa ra. Lưu ý rằng nó gần với giải pháp bởi @OdeToCode (nhưng trong cú pháp VB) đề xuất, với một sự khác biệt lớn:

Dim temp = _ 
    (From t In context.MyTable _ 
    Group t.f1, t.f2, t.f3 By t.title Into g = Group _ 
    Select title, g).ToList 

Dim results = _ 
    From t In temp _ 
    Select t.title, _ 
     f1_count = t.g.Count(Function(x) If(x.f1, False)), _ 
     f2_count = t.g.Count(Function(x) If(x.f2, False)), _ 
     f3_count = t.g.Count(Function(x) If(x.f3, False)) 

Truy vấn đầu tiên thực hiện các nhóm, nhưng ToList được các dữ liệu được nhóm như nó vốn có từ máy chủ . Loại bỏ việc đếm ở đây giữ câu lệnh SQL kết quả từ việc tạo ra các SELECT con cho mỗi số đếm. Tôi làm đếm trong truy vấn thứ hai cục bộ.

Điều này hoạt động vì tôi biết truy vấn đầu tiên sẽ trả lại số lượng hàng có thể quản lý. Nếu nó trở về hàng triệu hàng, tôi có lẽ sẽ phải đi theo một hướng khác.

+2

Không sử dụng tính năng này cho các tập dữ liệu lớn! Vui lòng không sao chép và dán nội dung này vào ứng dụng của bạn. Nên có một cảnh báo rất lớn về câu trả lời này. –

2

Tôi nghĩ đây là nơi LINQ rơi xuống. Nếu bạn muốn sử dụng hiệu quả SQL, nếu bạn muốn mã đẹp, hãy sử dụng LINQ.

Bạn luôn có thể thực hiện truy vấn trực tiếp vì bạn đã biết SQL.

class TitleCount { 
    public string Title; 
    public int Count1; 
    public int Count2; 
    public int Count3; 
} 

DataContext dc = new DataContext("Connection string to db"); 

IEnumerable<TitleCount> query = dc.ExecuteQuery<TitleCount>(
    @"SELECT title, 
      COUNT(f1) as Count1, 
      COUNT(f2) as Count2, 
      COUNT(f3) as Count3 
     FROM myTable GROUP BY title"); 
4

Nếu bạn muốn dính vào một truy vấn LINQ và sử dụng một loại vô danh, truy vấn có thể trông giống như:

var query = 
     from r in ctx.myTable 
     group r by r.title into rgroup 
     select new 
     { 
      Title = rgroup.Key, 
      F1Count = rgroup.Count(rg => rg.f1 == true), 
      F2Count = rgroup.Count(rg => rg.f2 == true), 
      F3Count = rgroup.Count(rg => rg.f3 == true) 
     }; 

Bí quyết là để nhận ra rằng bạn muốn đếm số lượng các lĩnh vực thực (nó được ánh xạ như là một bool nullable), mà bạn có thể làm với toán tử Count và một vị từ. Thông tin thêm về toán tử nhóm LINQ tại đây: The Standard LINQ Operators

+3

Đó là giải pháp mà tôi đã đưa ra ban đầu, nhưng truy vấn kết quả sử dụng các lựa chọn phụ để tạo ra từng số riêng lẻ. Trên một bảng với một nửa triệu hàng (không có chỉ mục), phiên bản này mất 7 giây, trong khi SQL thích hợp với 3 COUNT là tức thời. – gfrizzle