sql – 实体框架中的Row_number(由yyy分区)
发布时间:2020-12-12 06:33:45 所属栏目:MsSql教程 来源:网络整理
导读:我想通过使用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 JOI
我想通过使用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 这个问题是我的期待. 我尝试使用这个表达式,但遗憾的是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(); 我在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(); ***通过此查询解决 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(); 解决方法从您的SQL查询中,我认为您需要首先按PARTITION BY子句中的内容对它们进行分组,按日期对每个组进行排序.然后对每个组进行投影以包含每个条目及其索引.然后SelectMany展平所有组,然后应用过滤器,最后投影所需的结果.你可以看到我们根本不需要所谓的Zip.编辑:因为您需要对行号进行过滤,但看起来像接受表达式的Select方法< Func< T,int,TResult>>不受支持(以及Linq To Entity中的Zip方法).我不认为这是构建表达式树的问题,这意味着即使手动构建它,它仍然不会被支持.我认为你可以使用一些解决方法,你仍然可以使用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(); 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(); 我希望你理解在各种情况下使用Skip和Take的想法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |