LINQ to SQL Every Nth Row From Table

前端 未结 6 1549
情歌与酒
情歌与酒 2020-12-09 17:30

Anybody know how to write a LINQ to SQL statement to return every nth row from a table? I\'m needing to get the title of the item at the top of each page in a paged data gr

相关标签:
6条回答
  • 2020-12-09 18:12

    Sometimes, TSQL is the way to go. I would use ExecuteQuery<T> here:

        var data = db.ExecuteQuery<SomeObjectType>(@"
    SELECT * FROM 
    (SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS [__row]
    FROM [YourTable]) x WHERE (x.__row % 25) = 1");
    

    You could also swap out the n:

        var data = db.ExecuteQuery<SomeObjectType>(@"
    DECLARE @n int = 2
    SELECT * FROM 
    (SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS [__row]
    FROM [YourTable]) x WHERE (x.__row % @n) = 1", n);
    
    0 讨论(0)
  • 2020-12-09 18:18

    Here's an option that works, but it might be worth checking that it doesn't have any performance issues in practice:

    var nth = 3;
    var ids = Table
                .Select(x => x.Id)
                .ToArray()
                .Where((x, n) => n % nth == 0)
                .ToArray();
    
    var nthRecords = Table
                       .Where(x => ids.Contains(x.Id));
    
    0 讨论(0)
  • 2020-12-09 18:19

    This will do the trick, but it isn't the most efficient query in the world:

    var count = query.Count();
    var pageSize = 10;
    var pageTops = query.Take(1);
    for(int i = pageSize; i < count; i += pageSize)
    {
        pageTops = pageTops.Concat(query.Skip(i - (i % pageSize)).Take(1));
    }
    return pageTops;
    

    It dynamically constructs a query to pull the (nth, 2*nth, 3*nth, etc) value from the given query. If you use this technique, you'll probably want to create a limit of maybe ten or twenty names, similar to how Google results page (1-10, and Next), in order to avoid getting an expression so large the database refuses to attempt to parse it.

    If you need better performance, you'll probably have to use a stored procedure or a view to represent your query, and include the row number as part of the stored proc results or the view's fields.

    0 讨论(0)
  • 2020-12-09 18:28

    Just googling around a bit I haven't found (or experienced) an option for Linq to SQL to directly support this.

    The only option I can offer is that you write a stored procedure with the appropriate SQL query written out and then calling the sproc via Linq to SQL. Not the best solution, especially if you have any kind of complex filtering going on.

    0 讨论(0)
  • 2020-12-09 18:28

    There really doesn't seem to be an easy way to do this:

    How do I add ROW_NUMBER to a LINQ query or Entity?

    How to find the ROW_NUMBER() of a row with Linq to SQL

    But there's always:

    peopleToFilter.AsEnumerable().Where((x,i) => i % AmountToSkipBy == 0)
    

    NOTE: This still doesn't execute on the database side of things!

    0 讨论(0)
  • 2020-12-09 18:33

    Once upon a time, there was no such thing as Row_Number, and yet such queries were possible. Behold!

    var query =
      from c in db.Customers
      let i = (
        from c2 in db.Customers
        where c2.ID < c.ID
        select c2).Count()
      where i%3 == 0
      select c;
    

    This generates the following Sql

    SELECT [t2].[ID], [t2]. --(more fields)
    FROM (
        SELECT [t0].[ID], [t0]. --(more fields)
    (
            SELECT COUNT(*)
            FROM [dbo].[Customer] AS [t1]
            WHERE [t1].[ID] < [t0].[ID]
            ) AS [value]
        FROM [dbo].[Customer] AS [t0]
        ) AS [t2]
    WHERE ([t2].[value] % @p0) = @p1
    
    0 讨论(0)
提交回复
热议问题