【问题标题】:Translating SQL to lambda with groupby使用 groupby 将 SQL 转换为 lambda
【发布时间】:2013-04-12 20:05:01
【问题描述】:

我正在尝试翻译这条 sql 语句

SELECT row, SUM(value) as VarSum, AVG(value) as VarAve, COUNT(value) as TotalCount 
FROM MDNumeric
WHERE collectionid = 6 and varname in ('C3INEV1', 'C3INEVA2', 'C3INEVA3', 'C3INVA11', 'C3INVA17', 'C3INVA19')
GROUP BY row

使用 lambda 表达式进入 EF 4 查询,但我遗漏了一些东西。

我有:

sumvars = sv.staticvararraylist.Split(',');

var aavresult = _myIFR.MDNumerics
    .Where(r => r.collectionid == _collid)
    .Where(r => sumvars.Contains(r.varname))
    .GroupBy(r1 =>r1.row)
    .Select(rg =>
          new
          {
              Row = rg.Key,
              VarSum = rg.Sum(p => p.value),
              VarAve = rg.Average(p => p.value),
              TotalCount = rg.Count()
          });

其中 staticvararraylist 具有字符串 'C3INEV1'、'C3INEVA2'、'C3INEVA3'、'C3INVA11'、'C3INVA17'、'C3INVA19'(不带单引号)和 _collid 变量 = 6。

虽然我得到了正确的分组,但我的总和、平均值和计数值不正确。

【问题讨论】:

  • row 的类型是什么?是否实现IEquatable<T>

标签: c# sql lambda linq-to-entities


【解决方案1】:

您没有发布错误消息,但我怀疑它与Contains 有关。我发现Any 也同样有效。

这应该让你非常接近:

var result =
    from  i in _myIFR.MDNumerics
    where i.collectionid == _collid && sumvars.Any(v => i.varname == v)
    group i by i.row into g
    select new {
        row = g.Key,
        VarSum = g.Sum(p => p.value),
        VarAve = g.Average(p => p.value),
        TotalCount = g.Count()
    };

【讨论】:

  • 没有得到任何错误,问题是结果集计算不正确。例如,对于 row = 1 的记录,SQL 语句给出 VarSum = 30、VarAve= 5、TotalCount = 6。这个和 Fabrice 的 lambda 版本的结果集给出 VarSum=5、VarAve = 5.0 和 TotalCount = 1。 (我假设 select new 中的 's.Sum' 是 'g.Sum')。看起来它没有汇总所有记录。表中有几条记录在“行”字段中具有相同的值,我正在尝试根据所有相关的行值提取统计信息。
  • row = 1 的表中的数据包括这些记录:/row Total Average Count / 1 5 5 5 / 1 5 5 5 / 1 5 5 5 / 1 5 5 5 / 1 5 5 5 / 1 5 5 5 /
  • @DeeDub84,您处理的每件商品都有唯一的 ID 吗?如果没有,您可能会发现在使用实体框架时从 select 语句中排除了行,具体取决于您使用它的方式。无论如何,我认为您的问题中没有足够的信息来了解如何为您提供帮助。
  • 我认为问题出在 .Contains 或 .Any 中。它只选择与列表中的第一项匹配的表行,而不是与任何项目匹配的表行。目前 sumvars 是一个 string[] ,由 sumvars = sv.staticvararraylist 填充,这是一个以逗号分隔的列表的字段。我想选择 varname 在 sumvars 列表中的行。不过肯定有问题。
  • 我建议您尝试使用 LINQpad。它理解 EF 并将向您展示它为给定的 LINQ-to-Entities 表达式生成的 SQL。
【解决方案2】:

试试这个:

var aavresult = _myIFR.MDNumerics
.Where(r => r.collectionid == _collid && sumvars.Contains(r.varname))
.GroupBy(r1 =>r1.row,
  (key,res) =>    new
      {
          Row = key,
          VarSum = res.Sum(r1 => r1.value),
          VarAve = res.Average(r1 => r1.value),
          TotalCount = res.Count()
      });

【讨论】:

  • Fabrice,请参阅我对 Drew 的评论。结果集没有对所有记录求和/平均/计数。
猜你喜欢
  • 2013-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-27
  • 2022-01-19
  • 1970-01-01
相关资源
最近更新 更多