开发者

TotalRowCount with paging in Linq2SQL

Im getting a paged datasource from a fairly complex linq query. My problem is that is takes twice as long to execute since I need to get the total row count before paging is applied in order to calculate the nr. of pages to dispaly开发者_运维技巧. (the query will be executed twice)

Is there somehow I can do this in a more optimal way? Like using SQL's @@rowcount somehow?

This is roughly what the query looks like right now. (using Dynamic linq)

    public IList<User> GetPagedUsers(string filter, string sort, int skip, 
       int take, out int totalRows)
    {
            using(var dbContext = new DataContext())
            {
               IQueryable<User> q = GetVeryComplexQuery(dbContext);

               //Apply filter if exists
               if (!string.IsNullOrEmpty(filter))
                   q = q.Where(filter);

               //Set total rows to the out parameter
               totalRows = q.Count(); //Takes 4 sec to run

               //Apply sort if exists
               if (!string.IsNullOrEmpty(sort))
                   q = q.OrderBy(sort);

               //Apply paging and return
               return q.Skip(skip).Take(take).ToList(); //Takes 4 sec to run
            }
    }

Why wont this for example work?

TblCompanies.Dump(); //150 rows
ExecuteQuery<int>("select @@ROWCOUNT").Dump(); //returns 0


Linq2Sql will actually translate the use of Skip & Take into the SQL Statement so even if you could get @@RowCount the value will not be great than your take parameter.

If we take the following simple example (lifted from MSDN http://msdn.microsoft.com/en-us/library/bb386988.aspx).

IQueryable<Customer> custQuery3 =
    (from custs in db.Customers
     where custs.City == "London"
     orderby custs.CustomerID
     select custs)
    .Skip(1).Take(1);

foreach (var custObj in custQuery3)
{
    Console.WriteLine(custObj.CustomerID);
}

the following SQL is generated

SELECT TOP 1 [t0].[CustomerID], [t0].[CompanyName],
FROM [Customers] AS [t0]
WHERE (NOT (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM (
        SELECT TOP 1 [t1].[CustomerID]
        FROM [Customers] AS [t1]
        WHERE [t1].[City] = @p0
        ORDER BY [t1].[CustomerID]
        ) AS [t2]
    WHERE [t0].[CustomerID] = [t2].[CustomerID]
    ))) AND ([t0].[City] = @p1)
ORDER BY [t0].[CustomerID]

So you can see that the skip is actually occurring inside the SQL Statement and therefore @@RowCount is going to equal the amount of rows returned by the query and not the entire result set.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜