【问题标题】:Row_number over (Partition by yyy) in Linq?Linq中的行号超过(yyy分区)?
【发布时间】:2014-12-12 13:51:53
【问题描述】:

我对 LINQ 非常陌生,我第一次尝试使用它时必须非常复杂!

我正在尝试调整此 Stack Over question 中已接受的答案。

我是这样写的:

using (var ctx = new MyEntities())
        {
            var q = ctx.tblPrices.OrderByDescending(x => x.Cost)
                .GroupBy(x => x.ItemID)
                .Select(g => new {g, count = g.Count()})
                .SelectMany(t => t.g.Select(b => b).Zip(Enumerable.Range(1, t.count), (j, i) => new {j.WebPrice, j.PriceID, j.ItemID}));

            foreach (var i in q)
            {
                sb.AppendFormat("Id = {0}, Name = {1}, ItemId = {2}<hr/>", i.WebPrice, i.PriceID, i.ItemID);
            }

        }

基本上,我想为不同供应商的相同商品以最便宜的价格退货。

但是,当我运行该项目时,我收到以下很长的错误消息,我不知道这意味着什么。但是看起来很严重!

LINQ to Entities 无法识别该方法 'System.Collections.Generic.IEnumerable1[&lt;&gt;f__AnonymousType53[System.Nullable1[System.Decimal], System.Int32,System.Int32]] Zip[tblPrice,Int32,<>f__AnonymousType53](System.Collections.Generic.IEnumerable1[MyProjectMVC.Models.tblPrice], System.Collections.Generic.IEnumerable1[System.Int32], System.Func3[MyProjectMVC.Models.tblPrice,System.Int32, <>f__AnonymousType53[System.Nullable`1[System.Decimal],System.Int32,System.Int32]])' 方法,并且该方法不能翻译成商店表达式。

任何帮助将不胜感激。

【问题讨论】:

  • 问题可能出在 Enumerable.Range(1, t.count)?我认为 LINQ to SQL 不支持它
  • 您的答案在这里:method cannot be translated into a store expression. Linq to SQL 无法将您的部分查询转换为 SQL 命令。您可能必须先从数据库中获取结果(一个简单的.ToList 通常可以解决问题)然后处理它们。
  • 当您说来自不同供应商的最便宜的价格时,您的意思是结果将为每个唯一的ItemID 提供一个条目,同时WebPricePriceID 代表最便宜的价格?跨度>
  • 再看,var q = ctx.tblPrices.OrderBy(x =&gt; x.ItemID).ThenByDescending(x =&gt; x.Cost); 不告诉你你需要什么吗?
  • supplierId 和 itemId 会有一个价格。可能有服务器 itemId,但有不同的供应商和不同的价格。下面的查询看起来像是在做它的工作。呃,我怎么不太清楚!

标签: c# asp.net-mvc linq


【解决方案1】:

@Adil Mammadov 对,这是因为 LINQ 无法将方法转换为 SQL。

为避免此问题,您有多种解决方案:

  1. 指定 MS SQL 计算列并使用 LINQ 获取它
  2. 将您的 ows 转换写入 SQL
  3. @Matt Burland 怎么说 - 获取结果然后处理它

我想在你的情况下问题可以这样解决:

var q = ctx.tblPrices.OrderByDescending(x => x.Cost)
                .ToList()
                .GroupBy(x => x.ItemID)
                .Select(g => new {g, count = g.Count()})
                .SelectMany(t => t.g.Select(b => b).Zip(Enumerable.Range(1, t.count), (j, i) => new {j.WebPrice, j.PriceID, j.ItemID}));

甚至像这样:

var q = ctx.tblPrices.OrderByDescending(x => x.Cost)
                .GroupBy(x => x.ItemID)
                .Select(g => new {g, count = g.Count()})
                .ToList()
                .SelectMany(t => t.g.Select(b => b).Zip(Enumerable.Range(1, t.count), (j, i) => new {j.WebPrice, j.PriceID, j.ItemID}));

您也可以查看this my answer

【讨论】:

  • ToList 通常是解决这些问题的最简单方法。此外,使用 ToList 会关闭 DataReader,因此在 Web 应用程序中运行 Linq 时不会遇到锁定的 dataReader 问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-10
  • 1970-01-01
  • 2016-02-13
  • 2023-03-12
  • 2017-08-11
  • 2014-12-11
相关资源
最近更新 更多