【问题标题】:How to select a collection nested within another collection in LINQ如何在 LINQ 中选择嵌套在另一个集合中的集合
【发布时间】:2011-05-13 11:21:40
【问题描述】:

假设我有以下内容:

(--> = 1 到许多在 EF 代码优先中作为集合实现)

消息 --> 用户消息

消息 --> 附件

当我调用以下命令时:

var res = _ctx.DataContext.UserMessage.Where(x => x.UserId)
                                      .Select(m => m.Message).ToList();

编辑:添加类:

public class Message
{
    public int MessageId { get; set; }

    public ICollection<Attachment> Attachments { get; set; }

    [Required]
    public string Text { get; set; }      
}



    public class Attachment
    {
        public int AttachmentId { get; set; }

        public int MessageId { get; set; }
        public virtual Message Message { get; set; }

        public string FileServerPath { get; set; }
    }



    public class UserMessage
    {
        public int UserMessageId { get; set; }

        [Required]
        public int MessageId { get; set; }
        public Message Message { get; set; }

        [Required]
        public int UserId { get; set; }
        public User User { get; set; }        
    }

我希望 res 变量可以保存所有附件,但即使有行,它也是空的。我错过了什么?

【问题讨论】:

    标签: linq ef-code-first


    【解决方案1】:

    您的 where 条件没有意义,我什至认为它无法编译。
    您说,您希望res 保存所有附件。为什么要呢?您甚至不会在查询中的任何地方使用附件。
    如果没有您的实际课程,很难提出正确的方法,但我认为应该是这样的:

    var res = _ctx.DataContext.UserMessage.Where(x => x.UserId == currentUserId)
                                          .SelectMany(m => m.Message.Attachments)
                                          .ToList();
    

    现在,res 包含 ID 为 currentUserId 的用户的所有消息的所有附件。

    我假设类布局是这样的:

    class UserMessage
    {
        public int UserId {get;set;}
        public Message Message {get;set;}
    }
    
    class Message
    {
        public IEnumerable<Attachment> Attachments {get;set;}
    
        // Irrelevant for the query in its current form:
        public IEnumerable<UserMessage> UserMessages {get;set;}
    }
    

    【讨论】:

    • 我添加了更多类,以便您可以看到我的结构与您的不同。这是在代码优先和 EF 的上下文中,因此类中的 Id 和表的重复以表示关系并指定 FK。
    • @jaffa:请试试我的代码。关于相关部分,您的课程与我的课程相同。
    • 我已将其设置为已回答,但最终实现它略有不同。我的“聚合根”现在是父类,在嵌套类上使用 Include() 方法,而嵌套类又包含集合。
    【解决方案2】:

    在上下文中,它需要被告知获取带有包含的导航属性,例如

    _ctx.UserMessage.Include("Attachments")
                    .SelectMany( ... )
    

    HTH

    【讨论】:

    • 这看起来不对,如果您已经在上下文中查询它,为什么还要包含“UserMessage”?
    • @Jaffa 是的,您是对的,您不会在包含中获得顶级项目。一个只做子项目,所以我编辑了帖子。谢谢
    猜你喜欢
    • 2013-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2021-10-11
    相关资源
    最近更新 更多