0

With these simple classes:

public class Object
{
    List<Sheet> Sheets { get; set; }
}

public class Sheet
{
    List<Line> Lines { get; set; }
}

public class Line
{
    int LineId { get; set; }
}

I am trying to build a LINQ query that finds the single sheet with a corresponding lineId. In this case, a lineId is unique to one sheet. That is, a sheet can have multiple lines, but no two sheets can share identical lines.

The basic foreach code looks something like this, given an Object:

        Sheet targetSheet  = null;
        foreach (var sh in Sheet)
        {
            foreach (var l in sh.Lines)
            {
                if (l.Id == command.LineId)
                {
                    targetSheet = sh;
                    break;
                }
            }
        }

My (broken) attempt at a LINQ query with Lambda expressions:

Sheet targetSheet = Sheets.SingleOrDefault(s => s.Lines.Where(line => line.Id == command.LineId));

Can anyone see help me see what I am missing with this lambda expression?

Lamar
  • 581
  • 7
  • 22
  • 1
    Does this answer your question? [linq question: querying nested collections](https://stackoverflow.com/questions/721395/linq-question-querying-nested-collections) This might be helpful as well [Use LINQ to find value inside a nested collection](https://stackoverflow.com/questions/42404998/use-linq-to-find-value-inside-a-nested-collection) – Pavel Anikhouski Mar 27 '20 at 09:09
  • @PavelAnikhouski. Yes, first link has a very clear answer and includes my requirement of single. Thanks! – Lamar Mar 27 '20 at 21:20

1 Answers1

3

Try:

obj.Sheets.SingleOrDefault(s => s.Lines.Any(line => line.LineId == command.LineId))

The reason your code is not working is because you need a predicate delegate which returns a boolean value, whereas your lambda returns an IEnumerable<Line>.

weichch
  • 9,306
  • 1
  • 13
  • 25
  • Thank your for your explanation about the return type inconsistency and SelectMany. However, this expression still just returns a line since the line expression is subsequently chained, when I am actually just trying to get the target sheet. – Lamar Mar 26 '20 at 21:26
  • @Lamar Ah, sorry I misunderstood you. See updated. – weichch Mar 26 '20 at 21:38
  • Thanks! The above seems to work as expected in my case. – Lamar Mar 26 '20 at 21:43