2015-10-13 17 views
8

Tôi muốn tải dữ liệu bằng Row_number qua Phân vùng bằng cách sử dụng EF.Row_number over (Phân vùng theo yyy) trong Entity Framework

SELECT * 
    FROM (
     SELECT sf.SerialFlowsId 
        ,sf.GoodsSerialId 
        ,d.FormTypeId 
        , d.GoodsId 
        ,ROW_NUMBER() OVER (PARTITION BY d.GoodsId, sf.GoodsSerialId ORDER BY sf.Date DESC)row 
     FROM sam.SerialFlows sf 
     INNER JOIN sam.Detail d ON d.DetailId = sf.DetailId 
     )z 
WHERE z.row =1 
     AND z.FormTypeId=7 
     AND z.GoodsId=51532 

truy vấn này là mong đợi của tôi.

tôi cố gắng sử dụng biểu thức này nhưng tiếc là Zip phương pháp khuyến nông không nhận ra trong ef

var goodsSerials = context.SerialFlows.OrderByDescending(x => x.Date).GroupBy(x => new { x.Detail.GoodsID, x.Date }) 
        .Select(g => new {g}) 
        .SelectMany(z => z.g.Select(c => c)).Zip(m, (j, i) => new { GoodSerial=j,j.Detail.FormTypeID,j.Detail.GoodsID,rn=i }) 
        .Where(x => x.rn== 1 && x.GoodsID== goodsId && x.FormTypeID==7).Select(x => x.GoodSerial).ToList(); 

tôi có hơn 20.000.000 bản ghi trong bảng SerialFlows.

** Sửa

var goodsSerials = context.SerialFlows 
              .Where(e => e.Detail.GoodsID == goodsId) 
              .GroupBy(x => x.GoodsSerialID) 
              .Select(g => g.OrderByDescending(e=>e.Date).Take(1)) 
              .SelectMany(e => e.Where(x=>x.Detail.FormTypeID==7).Select(z=>z.GoodsSerial)).ToList(); 

*** giải quyết bằng cách truy vấn

 var goodsSerials = context.SerialFlows 
              .Include(x => x.Detail) 
              .Where(e => e.Detail.GoodsID == goodsId) 
              .GroupBy(x => x.GoodsSerialID) 
              .Select(g => g.OrderByDescending(e => e.Date).Take(1).Where(x=>x.Detail.FormTypeID==7)) 
              .SelectMany(e => e.Select(z => z.GoodsSerial)).ToList(); 
+2

Tại sao bạn nên downvote? Có vẻ như là một câu hỏi hoàn hảo cho tôi. – pseudocoder

Trả lời

8

này Từ truy vấn SQL của bạn, tôi nghĩ rằng bạn cần phải nhóm đầu tiên tất cả chúng bằng những gì trong PARTITION BY khoản, đặt hàng mỗi nhóm theo Ngày. Sau đó, dự án mỗi nhóm bao gồm mỗi mục với chỉ mục của nó. Sau đó, SelectMany để làm phẳng tất cả các nhóm, sau đó áp dụng bộ lọc và cuối cùng là dự án kết quả bạn muốn. Bạn có thể thấy rằng chúng tôi không cần cái gọi là Zip.

Sửa: bởi vì bạn cần phải lọc trên số hàng nhưng trông giống như Select phương pháp chấp nhận một Expression<Func<T,int,TResult>> không được hỗ trợ (cũng như Zip phương pháp trong LINQ to Entity). Tôi không nghĩ rằng đó là vấn đề của việc xây dựng cây biểu thức, có nghĩa là thậm chí xây dựng nó bằng tay, nó vẫn sẽ không được hỗ trợ. Tôi nghĩ bạn có thể sử dụng một số công việc xung quanh mà bạn vẫn có thể lọc hàng bạn muốn sử dụng SkipTake thay thế.

Đoạn mã dưới đây sẽ lọc chỉ hàng đầu tiên trong mỗi nhóm (tương đương với điều kiện rn == 1):

var goodsSerials = context.SerialFlows 
          .Where(e => e.Detail.GoodsID == goodsId && 
             e.Detail.FormTypeID == 7) 
          .GroupBy(x => new { x.Detail.GoodsID, x.GoodsSerialId }) 
          .Select(g => g.OrderByDescending(e => e.Date) 
             .Take(1)) 
          .SelectMany(e => e).ToList(); 

Các Where bộ lọc cho chỉ 1 giá trị của GoodsID nên GroupBy không cần phải bao gồm các GoodsID vào chìa khóa, vì vậy nó sẽ đơn giản như thế này:

var goodsSerials = context.SerialFlows 
          .Where(e => e.Detail.GoodsID == goodsId && 
             e.Detail.FormTypeID == 7) 
          .GroupBy(x => x.GoodsSerialId) 
          .Select(g => g.OrderByDescending(e => e.Date).Take(1)) 
          .SelectMany(e => e).ToList(); 

tôi hy vọng bạn hiểu được ý tưởng của việc sử dụng SkipTake để áp dụng trong các trường hợp khác nhau.

+0

unforunently tôi đã có lỗi Thông tin bổ sung: LINQ to Entities không nhận ra phương pháp 'System.Collections.Generic.IEnumerable –

+0

@MahdiFarhani xem chỉnh sửa của tôi, có vẻ như chúng ta khó có thể trích xuất số hàng, nhưng với mục đích lọc , chúng tôi có một công việc khá tốt. –

+0

nó chạy, nhưng hiệu suất là không thể chấp nhận được. Nó mất hơn 4 phút và tôi đã hủy bỏ nó. –

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