EntityFramework do Paging on a query with a join

entity-framework join paging

Question

I have a query with a left join in it:

   var query = (from v in context.Vehicles

                //left join vehicleAttributes
                join va in context.VehicleAttributes on v.VehicleId equals va.VehicleId into vAttributes
                from vehicleAttributes in vAttributes.DefaultIfEmpty()

                where v.FleetId == fleetId

                select new { v, vehicleAttributes });

And now I need to do a paging on it.

this works but gets all rows, so much more than i actually need

query.ToList().Select(x => x.v).Distinct().Skip(10 * (page - 1)).Take(10).ToList();

this is what I tried instead but now I don't have the joint values

query.Select(x => x.v).Distinct().ToList().Skip(10 * (page - 1)).Take(10).ToList();

any ideas?

Thanks

1
4
6/11/2013 3:01:58 PM

Accepted Answer

The ToList() triggers the call to the database so you need to only do this after you apply the Skip and Take. You'll need an OrderBy clause as well.

You should be able to do something like this:

var data = (from v in context.Vehicles
         join va in context.VehicleAttributes on v.VehicleId equals va.VehicleId into vAttributes
         from vehicleAttributes in vAttributes.DefaultIfEmpty()
         where v.FleetId == fleetId
         select new { v, vehicleAttributes })
         .OrderBy(p => p.v.FleetId)
         .Skip(10 * (page - 1))
         .Take(10)
         .ToList();
6
6/11/2013 3:07:11 PM

Popular Answer

Don't call ToList before Skip. Doing so will return all the records in the database that match your query.

To use Skip on an EntityFramework query, you need to have an instance of IOrderedQueryable, so you need an OrderBy clause.

query
    .Select(x => x.v)
    .Distinct()
    .OrderBy(v => v.FleetId)
    .Skip(10 * (page - 1))
    .Take(10).ToList();

I've got a project that takes care of a lot of this functionality. It's available on NuGet (with an MVC counterpart) and Google Code.

Using it would look something like this:

var factory = new Pagination.PageSourceFactory {
    MaxItemsPerPage = 50,
    DefaultItemsPerPage = 20
};
var source = factory.CreateSource(query, page);


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow