Deep nesting when looping over an object model coming from a 3rd part
First of all, I would realise that

var levelOneEnumerator = rootObject.GetEnumerator();
while (levelOneEnumerator.MoveNext())
{
    var levelOneItem = levelOneEnumerator.Current as Foo_LevelOneItem;
    if (levelOneItem == null) continue;


is equivalent to the much shorter

foreach (var levelOneItem in rootObject.OfType&lt;Foo_LevelOneItem&gt;())
{


Then you will realise that you have several nested foreach loops which make for nicely-readable single-line nestings. So factor all the multi-line code into methods of its own. The end-result I got looks like this:

foreach (var levelOneItem in rootObject.OfType&lt;Foo_LevelOneItem&gt;())
    foreach (var levelTwoItem in levelOneItem.LevelTwoItems.OfType&lt;Foo_LevelTwoItem&gt;())
        yield return new FooBarsCollection
        {
            Prop1 = levelTwoItem.Prop1,
            Prop2 = levelTwoItem.Prop2,
            Prop3 = levelTwoItem.Prop3,
            FooBars = getFoobars(levelTwoItem)
        };

[...]

private static List&lt;FooBar&gt; getFoobars(Foo_LevelTwoItem levelTwoItem)
{
    var foobars = new List&lt;FooBar&gt;();

    foreach (var levelThreeItem in levelTwoItem.LevelThreeItems.OfType&lt;Foo_LevelThreeItem&gt;())
        foreach (var levelFourItem in levelThreeItem.LevelFourItems.OfType&lt;Foo_LevelFourItem&gt;())
            foreach (var levelFiveItem in levelFourItem.LevelFiveItems.OfType&lt;Foo_LevelFiveItem&gt;())
                foreach (var levelSixItem in levelFiveItem.LevelSixItems.OfType&lt;Foo_LevelSixItem&gt;())
                    processLevelSixItem(foobars, levelFiveItem, levelSixItem.Key);

    return foobars;
}

private static void processLevelSixItem(List&lt;FooBar&gt; foobars, Foo_LevelFiveItem levelFiveItem, Foo_LevelSixItemKey levelSixKey)
{
    var foobar = foobars.Where(x =&gt; x.Key == levelSixKey).FirstOrDefault();
    if (foobar == null)
    {
        foobar = new FooBar
        {
            LevelSixKey = levelSixKey,
            TransDate = levelFiveItem.TransDate,
            PaidAmount = 0
        };
        foobars.Add(foobar);
    }

    // * -1 because value should be positive, while product reports a negative (and vice versa)
    foobar.PaidAmount += (levelFiveItem.PaidAmount ?? 0) * -1;
}


Of course, you could further change this into a much more LINQy expression involving either SelectMany or the from query syntax, but to be honest, in your particular case I would leave it like this. It is very clear. In case you still want the query syntax, here is just getFoobars to give you the idea:

private static List&lt;FooBar&gt; getFoobars(Foo_LevelTwoItem levelTwoItem)
{
    var foobars = new List&lt;FooBar&gt;();

    var query =
        from levelThreeItem in levelTwoItem.LevelThreeItems.OfType&lt;Foo_LevelThreeItem&gt;()
        from levelFourItem in levelThreeItem.LevelFourItems.OfType&lt;Foo_LevelFourItem&gt;()
        from levelFiveItem in levelFourItem.LevelFiveItems.OfType&lt;Foo_LevelFiveItem&gt;()
        from levelSixItem in levelFiveItem.LevelSixItems.OfType&lt;Foo_LevelSixItem&gt;()
        select new { LevelFiveItem = levelFiveItem, Key = levelSixItem.Key };

    foreach (var info in query)
        processLevelSixItem(foobars, info.LevelFiveItem, info.Key);

    return foobars;
}