Entity Framework/Linq to SQL: Skip & Take

后端 未结 6 2384
一个人的身影
一个人的身影 2020-11-27 15:19

Just curious as to how Skip & Take are supposed to work. I\'m getting the results I want to see on the client side, but when I hook up the AnjLab SQL Profiler and look a

相关标签:
6条回答
  • 2020-11-27 15:23

    If you are using SQL Server as DB

    Then you can convert

    context.Users.OrderBy(u => u.Id)
    .Skip(() => 10)
    .Take(() => 5)
    .ToList
    

    =>

    SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[UserName] AS [UserName]
    FROM [dbo].[AspNetUsers] AS [Extent1]
    ORDER BY [Extent1].[Id] ASC
    OFFSET 10 ROWS FETCH NEXT 5 ROWS ONLY
    

    refrence: https://anthonychu.ca/post/entity-framework-parameterize-skip-take-queries-sql/

    0 讨论(0)
  • 2020-11-27 15:25

    I created simple extension:

    public static IEnumerable<T> SelectPage<T, T2>(this IEnumerable<T> list, Func<T, T2> sortFunc, bool isDescending, int index, int length)
    {
        List<T> result = null;
        if (isDescending)
            result = list.OrderByDescending(sortFunc).Skip(index).Take(length).ToList();
        else
            result = list.OrderBy(sortFunc).Skip(index).Take(length).ToList();
        return result;
    }
    

    Simple use:

    using (var context = new TransportContext())
    {
        var drivers = (from x in context.Drivers where x.TransportId == trasnportId select x).SelectPage(x => x.Id, false, index, length).ToList();
    }
    
    0 讨论(0)
  • 2020-11-27 15:30

    The following works and accomplishes the simplicity I was looking for:

    public IEnumerable<Store> ListStores(Expression<Func<Store, string>> sort, bool desc, int page, int pageSize, out int totalRecords)
    {
        List<Store> stores = new List<Store>();
        using (var context = new TectonicEntities())
        {
            totalRecords = context.Stores.Count();
            int skipRows = (page - 1) * pageSize;
            if (desc)
                stores = context.Stores.OrderByDescending(sort).Skip(skipRows).Take(pageSize).ToList();
            else
                stores = context.Stores.OrderBy(sort).Skip(skipRows).Take(pageSize).ToList();
        }
        return stores;
    }
    

    The main thing that fixed it for me was changing the Func sort parameter to:

    Expression<Func<Store, string>> sort
    
    0 讨论(0)
  • 2020-11-27 15:30

    Entity Framework 6 solution here...

    http://anthonychu.ca/post/entity-framework-parameterize-skip-take-queries-sql/

    e.g.

    using System.Data.Entity;
    ....
    
    int skip = 5;
    int take = 10;
    
    myQuery.Skip(() => skip).Take(() => take);
    
    0 讨论(0)
  • 2020-11-27 15:34

    As long as you don't do it like queryable.ToList().Skip(5).Take(10), it won't return the whole recordset.

    Take

    Doing only Take(10).ToList(), does a SELECT TOP 10 * FROM.

    Skip

    Skip works a bit different because there is no 'LIMIT' function in TSQL. However it creates an SQL query that is based on the work described in this ScottGu blog post.

    If you see the whole recordset returned, it probably is because you are doing a ToList() somewhere too early.

    0 讨论(0)
  • 2020-11-27 15:36

    Try this:

    public IEnumerable<Store> ListStores(Func<Store, string> sort, bool desc, int page, int pageSize, out int totalRecords)
    {
        var context = new TectonicEntities();
        var results = context.Stores;
    
        totalRecords = results.Count();
        int skipRows = (page - 1) * pageSize;
    
        if (desc)
            results = results.OrderByDescending(sort);
    
        return results.Skip(skipRows).Take(pageSize).ToList();
    }
    

    in truth, that last .ToList() isn't really necessary as you are returning IEnumerable...

    There will be 2 database calls, one for the count and one when the ToList() is executed.

    0 讨论(0)
提交回复
热议问题