views:

60

answers:

1

I have an entity object (Company) which has 1 or more subobjects (CompanyRevision) represented as a non-null FK relationship in the database. Using LINQ, I want to get all the Companies from the database, but I also only want the latest CompanyRevision for each company. This is how I do it today, but I have a feeling this could be done using one query.

IEnumerable<Company> companyList = from p in ctx.Company.Include("CompanyRevisions")
                                   select p;

foreach(Company c in companyList)
{
  CompanyRevision cr = (from p in c.CompanyRevisions
                        orderby p.Timestamp descending
                        select p).First();

  // Do something with c and cr...
}

As you can see, I would like to add this second LINQ query (the one that gets the latest CompanyRevision) into the first one, so that companyList[i].CompanyRevisions is basicly a list with just one entry (the latest one). I can't for the life of my figure out how to do this. Please help!

Thanks in advance

+2  A: 

how about this: mixing the linq language and extension methods:

var results = from p in ctx.Company.Include("CompanyRevisions") 
select new {Company = p, 
            Revision = p.CompanyRevisions.OrderByDescending(cr => cr.Timestamp).First()
           }

Each result now has a Company and Revision member.

It's possible that you could also do this -

var results = from p in ctx.Company.Include("CompanyRevisions") 
select new {Company = p, 
            Revision = (from pcr in p.CompanyRevisions
                       orderby pcr.Timestamp descending
                       select pcr).First()
           }

To give the same results.

Although that's a guess - I haven't labbed that one out; but it's how I would try it first.

Andras Zoltan
Although this will work, I'm afraid this solution will still translate into a full INNER JOIN on the SQL level and more data than is acutally needed will be returned from the database, which is one of the concerns here.
David
@David - it shouldn't - your current solution generates more data transfer between server and client than this one - as only the two records that you're interested in here will be returned in one round-trip for all companies. Your current solution returns the same data but in n + 1 roundtrips - where n is the number of companies in your first enumerable result.
Andras Zoltan
The `Include` is redundant here; it's unnecessary/useless when projecting. Worst case, it would force loading of the stuff David doesn't want. The rest of the answer is on the right track, though.
Craig Stuntz
@Craig - you're right about the `Include` of course - not enough sleep on my part! :)
Andras Zoltan