ekkis
ekkis

Reputation: 10226

Constructing a linq query

I have a Question (q) with many Answers, each Answer has a variety of Texts, differing in language. I want to write a query to return all the answers in a given language (Lang) but I'm having difficulty figuring it out... here's what I'm trying:

List<string> Answers = q.Answers
   .Select(x => x.Texts.Where(l => l.Language.ISO == Lang).Select(t => t.Value))
   .ToList();

which generates:

Cannot implicitly convert type 'System.Collections.Generic.List<System.Collections.Generic.IEnumerable<string>>' to 'System.Collections.Generic.List<string>'

maybe I can't have a select inside a select... and:

List<string> Answers = q.Answers
   .Select(x => x.Texts.Where(l => l.Language.ISO == Lang))
   .Select(t => t.Value)
   .ToList();

where I would have thought the first select returns a Text, which means the second select can find its .Value... but, no:

'System.Collections.Generic.IEnumerable<Website.Models.Text>' does not contain a definition for 'Value' and no extension method 'Value' accepting a first argument of type 'System.Collections.Generic.IEnumerable<Website.Models.Text>' could be found (are you missing a using directive or an assembly reference?)

...perhaps I'm close but I can't quite get it. how does one do this?

-- Edit --

the credit here goes to SLaks. Here's the final statement:

List<string> Answers = q.Answers
        .SelectMany(x => x.Texts)
        .Where(x => x.Language.ISO == Lang)
        .Select(x => x.Value)
        .ToList();

Upvotes: 1

Views: 101

Answers (2)

dtb
dtb

Reputation: 217263

You need to use SelectMany or (in LINQ syntax) a from ... from ... select expression:

var query = from answer in q.Answers
            from text in answer.Texts
            where text.Language.ISO == lang
            select text.Value;

var result = query.ToList();

The query selects the value of all texts in all answers to the question q where the text's language is lang.

Upvotes: 3

SLaks
SLaks

Reputation: 887305

You need to call .SelectMany() to flatten the list of sets of Texts (IEnumerable<IEnumerable<string>>) into a single set of Texts (IEnumerable<string>).

Upvotes: 2

Related Questions