2015-05-18 23 views
10

Nếu tôi sử dụng Chọn trên IQueryable trên kết quả khung thực thể của tôi, tôi sẽ nhận được 4 mục.IQueryable <T> cho kết quả khác với Danh sách <T>

Nếu tôi sử dụng Chọn trên một IQueryable.ToList() Tôi nhận được tất cả 36 mục.

Đây là mã của hàm:

public ImagesGetModelView Get(int start, int count) 
{ 
    if (count <= 0) count = 9; 
    else if (count > ImageHandler.MaxResult) count = ImageHandler.MaxResult;  

     IQueryable<Image> imagesList = ImagesHandler.FetchRangeScore(start, count) 
      .Where(m => m.Domain == Database.Enums.ImageDomain.Gfycat); 

     //Works using list :(
     //var list = imagesList.ToList(); 

     //Select all subreddits once 
     //Returns 4 instead of 36 if not using the list ... 
     //Returns 1 instead of 2 with Distinct() if not using the list 
     IEnumerable<Subreddit> subreddits = imagesList 
      .Select(m => m.Subreddit); //.Distinct();   

     ImagesGetModelView result = new ImagesGetModelView() 
     { 
      Items = imagesList, 
      Subreddits = subreddits 
     }; 

     return result; 
    } 

public IQueryable<Image> FetchRangeScore(int a_start, int a_count) 
    { 
     return Repository.AllQueryable().OrderByDescending(m => m.Score) 
      .Skip(a_start).Take(a_count); 
    } 

Trong số 36 mặt hàng 2 Subreddits sẽ khác nhau. Nhưng kể từ khi chỉ có 4 trong số 36 được lấy từ Select() nó chỉ tìm thấy 1 khác biệt. Vì vậy, có bất cứ điều gì tôi có thể làm với các biểu thức LINQ để có được dữ liệu chính xác để tuyên bố riêng biệt hoạt động hoặc tôi phải biến nó thành một Danh sách trước khi tiếp tục với các chức năng Chọn & Riêng biệt?

Chỉnh sửa:
bằng cách di chuyển vị trí satement từ đầu đến cuối toàn bộ truy vấn. Nó có vẻ hoạt động chính xác ngay bây giờ. Chọn trả về tất cả 36 mục e.t.c ... mà lần lượt làm cho công việc khác biệt vì nó có thể tìm thấy nhiều hơn 1 giá trị duy nhất.

public IQueryable<Image> FetchRangeScore(int a_start, int a_count) 
    { 
     return Repository.AllQueryable() 
      .Where(m => m.Domain == Database.Enums.ImageDomain.Gfycat) 
      .OrderByDescending(m => m.Score) 
      .Skip(a_start).Take(a_count); 
    } 
+0

Một số dữ liệu giả có thể giúp minh họa quan điểm của bạn tại đây. – neontapir

+1

Tôi khuyên bạn nên đặt các phiên bản riêng biệt của logic của bạn (hoặc đoạn mã thứ hai của những gì bạn đã thay đổi). Có thể khó theo dõi các nhận xét bên trong mã cần thay đổi (ví dụ: tôi không thể biết được ví dụ của bạn bị hỏng hay hoạt động chính xác). – Guvante

+1

Có lý do nào khiến bạn phân trang trước khi bạn gọi riêng biệt không? Tôi thường mong đợi thứ tự ngược lại. – Guvante

Trả lời

5

Nhiều khả năng mệnh đề Where của bạn hoạt động khác trong SQL Server so với trong .NET. Cụ thể, tùy thuộc vào cài đặt đối chiếu của bạn và như vậy, có khả năng các giá trị .Domain khác nhau chỉ bằng cách viết hoa hoặc giống như vậy, làm cho chúng "bằng nhau" với Gfycat trong SQL, nhưng không phải trong C#.

Bạn có thể chụp .ToString() trên số IQueryable<> để xem SQL nào đang được sản xuất và tự mình thử.

IQueryable<Image> imagesList = ImagesHandler.FetchRangeScore(start, count) 
    .Where(m => m.Domain == Database.Enums.ImageDomain.Gfycat); 
Debug.WriteLine(imagesList.ToString()); 
+0

Tôi tin rằng bạn là chính xác. Bạn đã làm cho tôi nhận ra tôi đã có một tuyên bố nơi có :) Tôi đã thêm nó một thời gian dài trước đây để thử nghiệm và trở thành mù với nó. Nó khá studly đặt khi bạn nhìn vào nó, nhưng số liệu là 35 subreddits của 1 loại trong số 36 vì vậy tôi không bao giờ nhận thấy nó là sai cho đến đêm qua. Khi tôi chuyển nó vào đầu truy vấn, tôi nhận thấy rằng Debug.WriteLine() không trả lại truy vấn phụ nữa và mọi thứ dường như hoạt động tốt. –

5

Thật khó để chắc chắn nếu không có dữ liệu nguồn, nhưng Distinct hoạt động khác khi được đẩy vào SQL.

Truy vấn SQL DISTINCT sẽ lấy các bản ghi trong đó tất cả các giá trị đều khác nhau. Khi bạn thực hiện cuộc gọi Distinct trên danh sách các đối tượng trong bộ nhớ, theo mặc định, nó sẽ sử dụng dụ bình đẳng. Vì vậy, bạn có thể lấy lại các đối tượng "trùng lặp" (các đối tượng mà tất cả các giá trị trường đều giống nhau), nhưng chúng sẽ là "các cá thể" riêng biệt, do đó, Distinct coi chúng là các đối tượng khác nhau.

Vì vậy, nó phụ thuộc vào những gì bạn muốn - Bạn muốn tất cả Subreddit giá trị bao gồm bản sao hay bạn muốn phân biệt giá trị?

Để trả lời câu hỏi của bạn - nếu bạn không muốn cuộc gọi Distinct truyền lại cho các SQL bạn có thể gọi AsEnumerable() thay vì ToList, mà làm cho tất cả thêm LINQ truy vấn LINQ-to-Objects (IEnumerable<T>) truy vấn thay vì Linq- đến- {bất cứ điều gì} (IQueryable<T>) truy vấn, mà không cần phải đặt các mục trong danh sách.

+0

Tôi chỉ muốn các giá trị khác biệt không trùng lặp. Tôi cần subreddits tách biệt rõ ràng cho kết quả. –

Các vấn đề liên quan