score:3

make an anonymous pair to iterate over.

 foreach(var pair in parcels
    .Where(p => p.Owners != null)
    .SelectMany(p => new { o = p.Owners, p })
    .OrderByDescending(x => x.o.RecordingDate ?? x.o.SaleDate ?? x.o.DateEntered)) {

    var owner = pair.o;
    var parcel = pair.p;

    // do stuff
 }
 // alternate syntax
 foreach(var pair in from p in parcels
                     where p.Owners != null
                     from o in p.Owners
                     orderby o.RecordingDate ?? o.SaleDate ?? o.DateEntered descending
                     select new { o, p }) {
     var owner  = pair.o;
     var parcel = pair.p;
     // do stuff
 }

score:0

You'll need to add the parcel to the item returned by SelectMany:

parcels
        .Where(p => !p.Owners.IsNullOrEmpty())
        .SelectMany(p => p.Owners.Select(o => new { Parcel = p, Owner = o }))
        .OrderByDescending(x => x.Owner.RecordingDate ?? x.Owner.SaleDate ?? x.Owner.DateEntered)
        .ForEach(item =>
        {
            Parcel p = item.Parcel;
            Owner o = item.Owner;
            ...
        }

Related Articles