Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# linq Select objects in list looking inside another list of objects

Tags:

c#

linq

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;}   

}

I would like to get all attachments in Attachments collection whose name ends with .pdf.

I tried the following:

List<MailMessage> list = new List<MailMessage>();
List<attachment> pdfAttachmentsCollection = list.Where(x => x.Attachments
                               .Where(attachment => 
                                attachment.Name.EndsWith(".pdf")).Select(y => y.Content));

However, this doesnt work. Any suggestions. It gives error:

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable ' to 'bool'

like image 805
Gauravsa Avatar asked Mar 06 '23 00:03

Gauravsa


1 Answers

A couple issues:

  • You need to SelectMany from the MailMessage object to get all attachments in a single collection
  • You're selecting y.Content which is byte[] but trying to get a list of Attachment
  • LINQ returns IEnumerables, not Lists

Rewritten, you probably want to do something like:

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

This is also a good candidate to write as a query expression:

IEnumerable<Attachment> pdfAttachmentsCollection = 
    from message in list 
    from attachment in message.Attachments
    where attachment.Name.EndsWith(".pdf")
    select attachment;

Both of these do the same thing, just with different syntax.

If you want this as a List<Attachment> you can also do .ToList() at the end of either query. As an IEnumerable, it won't be evaluated until you start iterating through it (and depending on how you use it, you might never have the full collection in memory at any time). However, if you do multiple iterations or operations on it, it'll cause it to be evaluated multiple times -- so in those cases .ToList() makes sense for sure.

like image 148
gregmac Avatar answered Mar 09 '23 09:03

gregmac