15

I'am trying to use LINQ to create a grouped list of documents based on metadata which is a list on the document.

Below is how my object structure looks:

List<Document>
         --> List<Metadata>
                      --> Metadata has a name and a value property.

I want to group the documents based on an metadata tag which has a name: ID and group them where the values for the ID property are the same.

I tried it like this:

var x = response.Document
         .GroupBy(d => d.Metadata.Where(dc => dc.Name == DocProperty.ID)
         .Select(dc => dc.Value));

This results in a list of single documents, but not grouped on ID.

Also thought about selecting a distinct list of ID's and then loop through the document list and find documents that match the ID. That one seems like a lot of overhead, because for every ID in the distinct list i have to go every time into the metadata list and find the documents and have to extra checks for multiple items found, get the property i need etc.

Anyone has a good idea about how to get this thing working?

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
ChristiaanV
  • 5,401
  • 3
  • 32
  • 42

1 Answers1

29
var x = from doc in source
        from meta in doc.Metadata
        where meta.Name == DocProperty.Id
        group doc by meta.Value;

Or (comments) as fluent notation:

var y = source
    .SelectMany(doc => doc.Metadata, (doc, meta) => new { doc, meta })
    .Where(pair => pair.meta.Name == DocProperty.Id)
    .GroupBy(pair => pair.meta.Value, pair => pair.doc);
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Is there an easy way to covert this to the fluent notation? I gave it a try, but not really sure where to put the GroupBy, so it can access the meta.value property. This is what i tried: var y = response.Document .GroupBy(d => d.DocumentCharacteristic .Where(dc => dc.Name == DocProperty.InvoiceNumber) .Select(dc => dc.Value)); – ChristiaanV Mar 10 '11 at 10:47