Mah*_*ani 15 sql entity-framework window-functions
我想通过使用EF在Row_number上分区加载数据.
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
Run Code Online (Sandbox Code Playgroud)
这个问题是我的期待.
我尝试使用这个表达式,但遗憾的是Zip扩展方法无法在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();
Run Code Online (Sandbox Code Playgroud)
我在SerialFlows表中有超过20000000条记录.
**编辑
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();
Run Code Online (Sandbox Code Playgroud)
***通过此查询解决
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();
Run Code Online (Sandbox Code Playgroud)
Kin*_*ing 12
从您的SQL查询,我认为你需要通过什么第一组所有这些PARTITION BY
条款,按日期排序每个组.然后对每个组进行投影以包含每个条目及其索引.然后SelectMany
展平所有组,然后应用过滤器,最后投影所需的结果.你可以看到我们根本不需要所谓Zip
的.
编辑:因为您需要对行号进行过滤,但看起来不支持Select
接受的方法Expression<Func<T,int,TResult>>
(以及Zip
Linq To Entity中的方法).我不认为这是构建表达式树的问题,这意味着即使手动构建它,它仍然不会被支持.我认为你可以使用一些解决方法,你仍然可以过滤你想要使用的行Skip
,Take
而不是.
以下代码将仅过滤每个组中的第一行(相当于条件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();
Run Code Online (Sandbox Code Playgroud)
Where
只有1个值的过滤器GoodsID
所以GroupBy
不需要包含GoodsID
在键中,所以它会更简单:
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();
Run Code Online (Sandbox Code Playgroud)
我希望您理解在各种情况下使用Skip
和Take
应用的想法.
归档时间: |
|
查看次数: |
7321 次 |
最近记录: |