【问题标题】:How to get the last messages among users with LINQ?如何使用 LINQ 获取用户之间的最后一条消息?
【发布时间】:2020-09-29 05:48:57
【问题描述】:

我有一个显示消息之间关系的表格。像这样:

我想从每个用户那里得到最后一条消息。因此,例如,结果将是表中的 id 91 和 id 92

var messages = await _dbContext.Messages.Include(x =>x.User).Where(x =>x.SenderId == userId | x.ReceiveId == userId).OrderByDescending(x =>x.CreatedAt).Select(x =>new Message {
  Id = x.Id,
  Content = x.Content,
  CreatedAt = x.CreatedAt,
  User = new User {
    Id = x.User.Id,
    UserName = x.User.UserName,
    Name = x.User.Name,
    LastName = x.User.LastName,
    Profil = x.User.Profil
  },
}).Distinct().ToListAsync();

我该怎么做?

【问题讨论】:

  • 所以您的意思是按发送者ID、接收者ID分组,按日期降序排列每个键的项目列表并选择第一个?

标签: c# .net linq


【解决方案1】:

答案是:EF 不支持的窗口函数。所以只需编写 SQL 并通过 Dapper 运行它

SELECT
   s.Id,
   s.SenderId,
   s.ReceiveId,
   s.Content,
   s.CreatedAt
FROM 
(
   SELECT
      m.Id,
      m.SenderId,
      m.ReceiveId,
      m.Content,
      m.CreatedAt,
      ROW_NUMBER() OVER (PARTITION BY m.ReceiveId ORDER BY m.CreatedAt DESC) AS RN
   FROM Messages m
) s
WHERE s.RN = 1

其他解决方案只是解决方法。如果您需要 LINQ 来完成此类任务,我已经第三次提出 linq2db.EntityFrameworkCore

var query = from m in Messages
   select new 
   {
      m.Id,
      m.SenderId,
      m.ReceiveId,
      m.Content,
      m.CreatedAt,
      RN = Sql.Ext.RowNumber().Over().PartitionBy(m.ReceiveId).OrderByDesc(m.CreatedAt).ToValue()
   }

var messageQuery = 
  from m in query
  where m.RN == 1
  select new
  {
     m.Id,
     m.SenderId,
     m.ReceiverId,
     m.Content,
     m.CreatedAt,      
  }

// switch to alternative LINQ Translator
messageQuery = messageQuery.ToLinqToDB();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-16
    • 1970-01-01
    • 2021-02-03
    • 2017-04-10
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多