【问题标题】:Self join with aggregate query in LINQ在 LINQ 中使用聚合查询进行自联接
【发布时间】:2014-11-14 06:47:32
【问题描述】:

我在 C# 中有一个模型类,它与带有实体框架的数据库相关联。在我的模型中,我记录了用户的值,以及记录条目的时间。我想要的是返回一组仅代表给定 UserID 的最新记录的条目。

我可以在 SQL 中使用聚合查询(最大日期,按用户 ID 分组)和自联接来将这些参数与正确的记录相匹配。

DECLARE @UserValues
    TABLE
    (
        id INT IDENTITY(1,1) PRIMARY KEY, 
        UserID INT, 
        Value CHAR, 
        RecordedAt DATETIME
    )

INSERT INTO @UserValues (UserID, Value, RecordedAt) SELECT 3, 'a', '2014-11-06';
INSERT INTO @UserValues (UserID, Value, RecordedAt) SELECT 3, 'b', '2014-11-08';
INSERT INTO @UserValues (UserID, Value, RecordedAt) SELECT 3, 'c', '2014-11-04';
INSERT INTO @UserValues (UserID, Value, RecordedAt) SELECT 5, 'f', '2014-11-03';
INSERT INTO @UserValues (UserID, Value, RecordedAt) SELECT 5, 'h', '2014-11-23';
INSERT INTO @UserValues (UserID, Value, RecordedAt) SELECT 5, 'w', '2014-11-07';

select straight_data.*
from
(
    select UserID          as UserID,
           MAX(RecordedAt) as RecordedAt
      from @UserValues
     group by UserID
) as max_date
join @UserValues as straight_data
  on max_date.RecordedAt = straight_data.RecordedAt
 and max_date.UserID     = straight_data.UserID

结果只是每个用户最近的记录:

id  UserID  Value   RecordedAt
5   5       h       2014-11-23 00:00:00.000
2   3       b       2014-11-08 00:00:00.000

在此处查看实际操作:http://sqlfiddle.com/#!6/7c4dc/1

所以问题是,我如何在 LINQ 中执行以下操作,例如,

ICollection<UserValues> MyUserValues;

【问题讨论】:

    标签: c# sql sql-server linq entity-framework


    【解决方案1】:

    您可以通过以下步骤在 linq 中执行此操作:

    按用户 ID 分组

    按 RecordedAt(降序)对每个组进行排序

    从每个“组”中选择第一个。

    var dataByUserAndMaxDate = 
        MyUserValues.GroupBy(m => m.UserId)
                    .Select(m => m.OrderByDescending(x => x.RecordedAt).First());
    

    如果您使用MoreLinq,还有一个MaxBy 扩展方法(仅用于linq to objects)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多