【问题标题】:How to filter entity framework result with multiple columns using a lambda expression如何使用 lambda 表达式过滤具有多列的实体框架结果
【发布时间】:2012-11-13 00:18:52
【问题描述】:

我有下表:

还有以下数据:

如何过滤结果,以便只从每个omraade_id 中获取最新行(按timestamp 降序排序)?

在这种情况下,ID 为:10101005 的行

--

根据@lazyberezovsky 的回答,我创建了以下表达式:

dbConnection = new ElecEntities();

            var query = from data in dbConnection.Valgdata
            orderby data.timestamp descending
            group data by data.omraade_id into g
            select g.FirstOrDefault();

            return query.ToList();

它返回两行 ID 为 3 和 4,这是数据库中的前两行,也是时间戳最低的行。知道为什么吗?

【问题讨论】:

    标签: c# linq entity-framework-4 lambda


    【解决方案1】:
    var query = dbConnection.Valgdata
                            .GroupBy(x => x.omraade_id)
                            .Select(g => g
                                 .OrderByDescending(x => x.timestamp)
                                 .FirstOrDefault());
    

    【讨论】:

    • 感谢您的尝试。这将返回所有 11 行(返回 row=3 9 次和 row=4 2 次)?
    • 再次感谢。我很感激你的努力。这将返回一个具有两个键的 Grouping 对象。第一个键包含第一个 omraade_id 中的所有行,第二个键包含第二个 omraade_id 中的所有行(未排序)。
    • @Kenci 我刚刚尝试过,对我来说效果很好。您确定所有括号都在正确的位置吗?
    • 我已经复制粘贴了你的答案。我已经上传了我在这里得到的图片:img202.imageshack.us/img202/6407/dbgroupquery.png
    • @Kenci 你是对的,对不起。显然,我在尝试将我拥有的内容转换为 Linq 语法时犯了一个错误。查看我的更新。
    【解决方案2】:

    我没有使用 EF 的经验,所以我不确定是否只有 SQL 风格的 linq 可以在这里工作。一个普通的 C#-ish:

    var query = dbConnection.Valgdata.GroupBy(u => u.omraade_id)
          .Select(x => x.FirstOrDefault(y => x.Max(p => p.timestamp) == y.timestamp));
    

    【讨论】:

    • @Kenci 为什么是 FirstOrDefault? First 适用于所有情况!因为无论如何你都会有一个最大的时间戳。
    • 时间戳列可以为空,当我使用 First() 执行查询时它会引发错误 - 但我可能应该更改它:)
    【解决方案3】:

    您已在每个项目上放置了过滤器。它应该应用于完整的查询结果,而不是每个项目。

    以下是更新的查询。

     var query = (from data in dbConnection.Valgdata
            orderby data.timestamp descending
            group data by data.omraade_id into g
            select g).FirstOrDefault();
    

    【讨论】:

    • 感谢您的回答。我已经尝试过你的建议,它返回 9 个结果(所有 id = 6 的行)
    【解决方案4】:
    var query = from v in dbConnection.Valgdata
                orderby v.timestamp descending
                group v by v.omraade_id into g
                select g.First();
    

    这将只返回每个 omraade_id 具有最大时间戳的记录。

    UPDATE 上面的查询对我来说很好(至少对于 MS SQL Linq 提供程序)。你也不需要FirstOrDefault - 如果 omraade_id 被分组,那么它肯定至少有一行。

    var query = from v in dbConnection.Valgdata
                group v by v.omraade_id into g
                select g.OrderByDesc(x => x.timestamp).First();
    

    【讨论】:

    • 如果我写降序或升序返回相同
    • @Kenci 查看更新的答案。也许它的 linq 提供程序特定问题。分组后尝试对记录进行排序。这绝对应该有效。
    【解决方案5】:

    这是我目前的解决方案:

    var data = dbConnection.Valgdata.Where(x => x.godkendt == false).ToList();
    var dataGrouped = data.GroupBy(x => x.omraade_id).ToList();
    
    List<Valgdata> list = new List<Valgdata>();
    
     foreach (var grpdata in dataGrouped)
                {
                    var dataGroup = grpdata.OrderByDescending(x => x.timestamp).ToList();
                    list.Add(dataGroup.FirstOrDefault());
                }
    return list;
    

    我不知道它是否最有效,但它确实有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 2012-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多