在一个对象列表中查找另一个对象列表中的对象——C# Linq选择

5

I have a class like this:

public class MailMessage
{
    public string From {get; set; };
    public string To {get; set; };   
    public ICollection<Attachment> Attachments { get; set; }
}

public class Attachment
{
  public string Name {get; set;} 
  public byte[] Content {get;set;}   

}

我希望获取附件集合中所有以“.pdf”结尾的附件。
我尝试了以下方法:
List<MailMessage> list = new List<MailMessage>();
List<attachment> pdfAttachmentsCollection = list.Where(x => x.Attachments
                               .Where(attachment => 
                                attachment.Name.EndsWith(".pdf")).Select(y => y.Content));

然而,这并不起作用。有什么建议吗?它会出现错误:

无法将类型'System.Collections.Generic.IEnumerable'隐式转换为'bool'


1
可能是Select和SelectMany之间的区别的重复问题。 - mjwills
1
那个错误可能来自于第一个where,因为它不是给定谓词的布尔表达式。 - Jonathan Van Dam
2
var pdfAttachmentsCollection = list.SelectMany(x => x.Attachments.Where(a => a.Name.ToLower().EndsWith(".pdf"))).ToList(); - Jimi
1
我建议从 list.SelectMany(x => x.Attachments) 开始。其余的是标准的 Where 东西,你会很容易地解决的。Jim 的方法同样适用。 - mjwills
1
更好的不区分大小写检查方式:Name.EndsWith(".pdf", StringComparison.InvariantCultureIgnoreCase) - gregmac
1个回答

10

有几个问题:

  • 您需要从MailMessage对象中SelectMany以获得单个集合中的所有附件
  • 您选择了y.Content,它是byte[],但尝试获取Attachment列表
  • LINQ返回的是IEnumerables,而不是List

修改后,您可能想要执行类似以下操作:

List<MailMessage> list = new List<MailMessage>();
IEnumerable<Attachment> pdfAttachmentsCollection = 
    list.SelectMany(message => 
        message.Attachments
            .Where(attachment => attachment.Name.EndsWith(".pdf")));

这也是一个可以写成查询表达式的好例子:
IEnumerable<Attachment> pdfAttachmentsCollection = 
    from message in list 
    from attachment in message.Attachments
    where attachment.Name.EndsWith(".pdf")
    select attachment;

这两个语法不同,但实现的功能相同。

如果您想将其作为 List<Attachment>,您也可以在任何一个查询的结尾处添加 .ToList()。作为IEnumerable,只有在开始迭代时才会被评估(并且根据您如何使用它,您可能永远没有完整的集合)。但是,如果您对其进行多次迭代或操作,则会导致它多次被评估--因此在这些情况下,.ToList() 是明智的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接