【问题标题】:Need help to convert T-Sql into Linq需要帮助将 T-Sql 转换为 Linq
【发布时间】:2014-02-01 16:09:51
【问题描述】:

之前没用过Linq,实在没时间学习。我的知识不足以做到这一点,我需要你的帮助。 这是我需要转换为 Linq 的代码。 (我正在使用 EF6 和上下文)

WITH messages AS (
    SELECT s.siteId,s.originator,s.sentTime,s.mode,s.mainsFrequency,s.gensetFrequency,
            s.dgBattery,s.runHours,s.fuel,s.messageID,s.messageText,
           ROW_NUMBER() OVER(PARTITION BY s.originator 
                                 ORDER BY s.sentTime DESC) AS rk
      FROM smsParseds s)
SELECT m.*
FROM messages m
WHERE m.rk = 1
order by m.sentTime DESC

【问题讨论】:

  • 如果您没有时间自己解决这个问题,是什么让您认为这里的任何人都应该花时间为您完成工作?
  • 谢谢。我检查了 dagarrison 和 Aducci 给出的两种方式。在职的。附言在 Linq 中“DESC”必须为“降序”。

标签: sql linq sql-to-linq-conversion


【解决方案1】:

Row_number over (Partition by xxx) in Linq? 用于进行分区。

其余的是相当基本的 linq 语法。

我没有对此进行测试或尝试编译它,因此可能需要稍作修改。为了清楚起见,我将类似于问题的查询分开,但这些可以很容易地组合成一行。

var messages = smsParseds
   .OrderBy(o => o.sentTime).GroupBy(g => g.originator)
   .Select(s => new {s, rk = s.Count()})
   .SelectMany(sm => sm.s.Select(b => b)
      .Zip(Enumerable.Range(1,sm.rk), (j,i) => new {j.siteId, j.originator, j.sentTime, j.mode, j.mainsFrequency, j.gensetFrequency, j.dgBattery, j.runHours, j.fuel, j.messageID, j.messageText, rk = i}));

var result = messages
   .Where(w => w.rk = 1)
   .OrderByDescending(o => o.sentTime)

【讨论】:

    【解决方案2】:

    这不是直接翻译(Entity Framework不能使用Row Number),但是结果应该是一样的

    var query = from m in context.Messages
                where (from x in context.Messages
                       where m.Originator == x.Originator
                       where x.SentTime > m.SentTime
                       select x).Any() == false
                orderby m.SentTime desc
                select new
                {
                  m.siteId,
                  m.originator,
                  m.sentTime,
                  m.mode,
                  m.mainsFrequency,
                  m.gensetFrequency,
                  m.dgBattery,
                  m.runHours,
                  m.fuel,
                  m.messageID,
                  m.messageText,
                };
    

    【讨论】:

    • 由于原始查询基于分区进行过滤,因此此查询将返回比预期更多的行。
    • @dagarrison,怎么会这样? where 子句仅包含来自每个 Originator 的最新记录。
    • 哦,我明白你在做什么了。你是对的,我的错。我总是需要一些时间来处理 x.SentTime > m.SentTime 正在做什么。
    猜你喜欢
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多