I think you need to use this overload of SelectMany
:
http://msdn.microsoft.com/en-us/library/bb534631(v=vs.110).aspx
But I also think you need to call it twice. Given the following structure, I came up with the following:
class Program
{
static void Main(string[] args)
{
var groups = new List<Group>();
var items = groups
.SelectMany(group => group.SubGroups, (group, subGroup) => new
{
group,
subGroup
})
.SelectMany(anon => anon.subGroup.Items, (anon, item) => new
{
Group = anon.group,
SubGroup = anon.subGroup,
Item = item
});
Console.Read();
}
}
class Group
{
public string GroupName { get; set; }
public List<SubGroup> SubGroups { get; set; }
}
class SubGroup
{
public string SubGroupName { get; set; }
public List<Item> Items { get; set; }
}
class Item
{
public string ItemName { get; set; }
}
Basically, you project forward to keep a reference to the parent item. In your specific structure, it would look like this:
var items = groups
.SelectMany(group => group.SubGroups, (group, subGroup) => new
{
group,
subGroup
})
.SelectMany(anon => anon.subGroup.Items, (anon, item) => new
{
anon.group.MainGroupId,
anon.subGroup.SubGroupId,
item.ItemMpId
});
This gives you a large list of anonymous type currently not filtered, if you want to filter the stuff as you go simply append a Where
call into the Items
merge:
var items = groups
.SelectMany(group => group.SubGroups, (group, subGroup) => new
{
group,
subGroup
})
.SelectMany(anon => anon.subGroup.Items.Where(item => item.ItemMpId == work.ItemMpId), (anon, item) => new
{
anon.group.MainGroupId,
anon.subGroup.SubGroupId,
item.ItemMpId
});
This should address your requirement of SelectMany
usage, however, I'm not convinced this is entirely readable.