Break it down into many simple queries, and then put those queries back together.
Let's start by making a sequence of items that match by name:
var nameMatches = from item in itemList where item.Name == p.Name select item;
We need to compare those items against the sequence of names in p's subitems. What's that sequence? Write a query:
var pnames = from subitem in p.SubItems select subitem.Name;
Now you want to find all the elements from nameMatches where the sequence of names matches. How are you going to get the sequence of names? Well, we just saw how to do that with pnames, so do the same thing:
var matches = from item in nameMatches
let subitemNames =
(from subitem in item.SubItems select subitem.Name)
where pnames.SequenceEqual(subitemNames)
select item;
And now you want to know, are there any matches?
return matches.Any();
That should work just fine as is. But if you want to be really buff you can write the whole thing in one big query!
return (
from item in itemList
let pnames =
(from psubitem in p.SubItems select psubitem.Name)
let subitemNames =
(from subitem in item.SubItems select subitem.Name)
where item.Name == p.Name
where pnames.SequenceEqual(subitemNames)
select item).Any();
And you're done. Easy as pie! Just remember, break it down into small steps, solve each problem individually, and then put the solution together out of the small results.