Emi
Emi

Reputation: 306

Linq query from multiple sets of nested collections

I'm a bit new to Linq. I'm trying to query a collection of items, that are distributed across multiple containing items. Basically, I'm trying to run a nested query on items in nested collections, that are selected based on some criteria.

Here is an example where I came up with a somewhat ugly method, that achieves the result.

Data item:

Class qItem
    Property qName As String
    Property qStrings As List(Of String)
End Class

Populated collections:

Dim qItems As New List(Of qItem)

qItems.Add(New qItem With {.qName = "Name1", .qStrings = New List(Of String) From {"3243", "324239", "f3f235423"}})
qItems.Add(New qItem With {.qName = "Name2", .qStrings = New List(Of String) From {"3243", "324239", "f3f235423"}})
qItems.Add(New qItem With {.qName = "Name1", .qStrings = New List(Of String) From {"3243r33", "3gfh465239", "r2r23r"}})
qItems.Add(New qItem With {.qName = "Name1", .qStrings = New List(Of String) From {"32f3f3f43", "324239", "f3f235423"}})

And the "ugly" query:

Dim myQuery = From q In qItems Where q.qName = "Name1"
Dim qResult As New List(Of String)
For Each qlst In myQuery
     qResult.AddRange(qlst.qStrings)
Next
Dim finalQuery = From q In qResult Where q.Contains("f3")

Can this be somehow done without running a manual for-each loop to aggregate all the items from different qStrings? To achieve this I would assume, I need to somehow do a From for all different items in my collection qitems.
In essence, for the result I need a collection of strings queried from q.qStrings from multiple qItem obejcts. How would I do this?

Upvotes: 0

Views: 639

Answers (2)

Emi
Emi

Reputation: 306

After more digging I found the answer I was looking for.
Turns out you can nest-chain From statements. Also I was not familiar with Select.
So, in the end, the working solution for my case is as simple as this.

Dim finalQuery = From q In qItems Where q.qName = "Name1"
                 From s In q.qStrings
                 Select s Where s.Contains("f3")

And to get a more general collection, a conversion can be added at the end.

Dim finalQuery = (From q In qItems Where q.qName = "Name1"
                 From s In q.qStrings
                 Select s Where s.Contains("f3")).ToList

Upvotes: 1

Gabriel Llorico
Gabriel Llorico

Reputation: 1803

You can extend it, basically adding (And or Or) will continue the Where clause.

In your example qStrings is a property of qItem and you want to query qStrings that contains "f3"

From q In qItems Where q.qName = "Name1" And q.qStrings.Contains("f3")

If qItem has additional property like int Id and want to filter it by 1

From q In qItems Where q.qName = "Name1" And q.qStrings.Contains("f3") And q.Id = 1

Upvotes: 1

Related Questions