c# - 使用 EF 选择组中的 TOP 元素

标签 c# entity-framework linq-to-entities

我有以下实体,基本上 UserMessage 通过 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/

相关文章:

database - Linq 到具有大数据库的实体

c# - 后台任务中的 IOC DI 多线程生命周期范围

c# - EntityKey 和 ApplyPropertyChanges()

linq - 无法创建常量值 - 仅允许原始类型或枚举类型

c# - Entity Framework 、dll、excel

c# - 使用 Web Api 2 Controller 测试的 Moq 在模拟 DbContext 中加载相关实体

c# - 选择数组中的每个整数

c# - 使用 QuickBooks Online (QBO) Intuit 合作伙伴平台 (IPP) DevKit 查询具有未结余额的所有发票

c# - 如何删除数据 GridView 中的一行并在删除按钮单击事件时更新 MySQL 数据库?

c# - 在 Windows Phone 8 模拟器中实现试用时出错