LeeFranke
LeeFranke

Reputation: 214

LINQ query to return grandparents that grandkids match value

The idea is to return a list of grandparents who have grandkids with the name of 'Bob'

List<GrandParent> g_rents = new List<GrandParent>();

class GrandParent
{
   public string Name { get; set; }
   public List<Parent> l_rents { get; set; }

   public GrandParent()
   {
      l_rents = new List<Parent>();
   }

}

class Parent
{
   public string Name { get; set; }
   public List<Child> l_kids { get; set; }

   public Parent()
   {
       l_kids = new List<Child>();
   }

}

class Child
{
   public string Name { get; set; }

}

I've tried 2 different queries:

   var y = g_rents.Where( p => p.l_rents.l_kids.Any(o => o.Name == "Bob") );

Has an error of:

'List<Parent>' does not contain a definition for 'l_kids' and no accessible extension method     'l_kids' accepting a first argument of type 'List<Parent>'

This query:

   var x = g_rents.Where(g => g.l_rents.Where(h => h.l_kids.Select(i => i.Name=="Bob"));
    

Had an error of:

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

I use LINQ just enough to know I'm probably missing something simple in them, but I can't figure out what.

thank you!

Upvotes: 0

Views: 130

Answers (2)

CoolBots
CoolBots

Reputation: 4889

You're almost there; you need Any on the l_rents as well:

g_rents.Where(g => g.l_rents.Any(p => p.l_kids.Any(k => k.Name == "Bob")));

The logic being, "for each grandparent g in the grandparents list g_rents, return those Where Any parent p in that grandparent's g parents list g.l_rents has Any kid k in that respective parent's kids list p.l_kids, who is named "Bob" (k.Name == "Bob").

Upvotes: 2

Arriel
Arriel

Reputation: 125

CoolBots is right. You need an .Any() in there. This is what I did, but now I realize the Where's are unnecessary. I'd go with CoolBots' answer.

 var grandParents = g_rents.Where(gp => gp.l_rents
                             .Where(p => p.l_kids
                               .Where(k => k.Name.Equals("Bob")).Any())
                              .Any()).ToList();

I had no idea you could throw a lambda in Any. The more you know...

Upvotes: 1

Related Questions