我有以下实体,基本上 User
和 Message
通过 MsgGroup
建立了 M2M 关系。此外,线程(或组)中的第一条消息具有 ThreadId=MessageId
,其他消息共享相同的 ThreadId
public class User
{
public int UserId { get; set; }
[System.ComponentModel.DataAnnotations.Schema.InverseProperty("Received")]
public virtual System.Collections.Generic.ICollection<MsgGroup> ReceivedGroups { get; set; }
}
public class Message
{
public int MessageId { get; set; }
public int ThreadId { get; set; }
public virtual System.Collections.Generic.ICollection<MsgGroup> MsgGroups { get; set; }
}
public class MsgGroup
{
public int MsgGroupId { get; set; }
public int UserId { get; set; }
public virtual User Received { get; set; }
public int MessageId { get; set; }
public virtual Message Message { get; set; }
}
我想为给定用户获取组中的迟到消息。特别是以下 SQL 查询:
select * from messages where MessageId IN (
SELECT MaxId FROM (
select ThreadId , MAX(MessageId) as MaxId from messages where ThreadId in (
select distinct MessageId from msggroups where UserId = 1
)
GROUP BY ThreadId
) AS t1
)
我试过:
var query = from grp in db.MsgGroups.Where(g => g.UserId == userId)
select new
{
f = (from msg in db.Messages where (msg.ThreadId == grp.MessageId) select msg).OrderByDescending(m => m.Date).Take(1)
};
然而,它创建了一个非常复杂的查询,其中每个消息字段都有子查询。
有解决办法吗?我也可以用基于方法的格式和查询表达式格式问同样的问题吗(因为我根本无法弄清楚查询表达式格式)
最佳答案
我认为您可能正在寻求加入,也许是这样的,这将为您提供特定用户的最新消息,按线程 ID 排序,您可以替换 Take 包含您想要的消息数的部分:
var query = (from grp in db.MsgGroups
.Join(
db.Messages,
g => g.MessageId,
m => m.ThreadId,
(g, m) => new { grp = g, mgs = m })
.Where(x => x.grp.UserId == userId)
select new
{
Message = grp.mgs
})
.Take(100)
.OrderByDescending(t => t.Message.ThreadId);
这将为您提供一组匿名对象,每个对象都有一个名为 Message 的属性,这就是您想要的 Message 对象。
关于c# - 使用 EF 选择组中的 TOP 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19653087/