Paging with Entity Framework 7 and SQL Server 2008
Asked Answered
B

7

24

I'm trying to use paging (that is .Skip(...).Take(...) in Entity Framework 7. It works OK with Microsoft SQL Server 2012 and 2014, but fails with the following error on SQL Server 2008:

System.Data.SqlClient.SqlException (0x80131904): Incorrect syntax near 'OFFSET'. Invalid usage of the option NEXT in the FETCH statement.

I've figured out that it is a breaking change in EF version 6.1.2 (http://erikej.blogspot.com/2014/12/a-breaking-change-in-entity-framework.html). But the fix is to modify EDMX file setting ProviderManifestToken attribute to "2008".

The problem is that EF7 currently only supports code-first scenario, thus there is no any EDMX out there. The question is: how to configure ASP.NET 5 website with Entity Framework 7 to use fallback pagination approach for SQL Server older than 2012?

Brookhouse answered 1/5, 2015 at 21:34 Comment(1)
Please see issue #1326 and add any comments you may have.Milone
C
16

I encountered this problem myself using EF 7 and sql server 2008. Fortunately in the latest rc1 version of EF 7 you can solve this by using .UseRowNumberForPaging() as shown in this example:

services.AddEntityFramework()
  .AddSqlServer()
  .AddDbContext<YourDbContext>(options =>
     options.UseSqlServer(configuration["Data:DefaultConnection:ConnectionString"])
                    // this is needed unless you are on mssql 2012 or higher
                    .UseRowNumberForPaging()
                );
Collettecolletti answered 8/12, 2015 at 20:39 Comment(2)
I did this, and I'm still encountering the said error.Algonquian
Not working in RC 1. Linq "Skip" still tries to generate OFFSET/FETCH NEXT syntax.Marseilles
K
43

If you use Edmx file, you must open the edmx file using XML Editor and change

ProviderManifestToken="2012" ==> ProviderManifestToken="2008"

in line 7.

Please take a look at this blog post for more information: http://erikej.blogspot.com.tr/2014/12/a-breaking-change-in-entity-framework.html

Kostman answered 30/5, 2015 at 17:58 Comment(5)
Thanks. Same problem resolved for when my azure database taken at local database.Octavalent
This saved me so much time and this deserves so much more attention. In my case, my development environment was SQL SERVER 2012 and my QA environment is 2008 R2.Hl
If it's changed to 2008, will it still be working with SQL Server 2012?Intitule
Confirmed. It works also for SQL Server 2012. Now, I believe this answer is from heaven !Intitule
It's 2019, and this fix still works perfectly. Now I wish someone would just update our DB from 2008... Come on DBAs, you can do it. :)Kellsie
C
16

I encountered this problem myself using EF 7 and sql server 2008. Fortunately in the latest rc1 version of EF 7 you can solve this by using .UseRowNumberForPaging() as shown in this example:

services.AddEntityFramework()
  .AddSqlServer()
  .AddDbContext<YourDbContext>(options =>
     options.UseSqlServer(configuration["Data:DefaultConnection:ConnectionString"])
                    // this is needed unless you are on mssql 2012 or higher
                    .UseRowNumberForPaging()
                );
Collettecolletti answered 8/12, 2015 at 20:39 Comment(2)
I did this, and I'm still encountering the said error.Algonquian
Not working in RC 1. Linq "Skip" still tries to generate OFFSET/FETCH NEXT syntax.Marseilles
L
5

This feature was removed in EF Core 3.x, UseRowNumberForPaging is marked as obsolete. However, you can use EfCore3.SqlServer2008Query package instead. There are 2 packages available in Nuget, one for >= .NET 5.0, other one is for >= .NET 3.1

enter image description here

Usage:

 services.AddDbContext<MyDbContext>(o => 
       o.UseSqlServer(Configuration.GetConnectionString("Default"))
        .ReplaceService<IQueryTranslationPostprocessorFactory, SqlServer2008QueryTranslationPostprocessorFactory>());
Lolalolande answered 3/2, 2021 at 11:40 Comment(0)
M
4

It's broken in RC 1. Gotta wait to get RC 2.

https://github.com/aspnet/EntityFramework/issues/4616

Marseilles answered 29/4, 2016 at 19:21 Comment(2)
Very useful link. It helped me to solve my problem using: options.UseSqlServer(connection, b => b.UseRowNumberForPaging());Criollo
Very helpful! useRowNumberForPaging() solved my issue!Pastelist
M
2

MyDbConnectionString is Connection string from any source

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlServer(_config["MyDbConnectionString"], 
                options=>
                {
                    options.UseRowNumberForPaging();
                });
}

UseRowNumberForPaging() solved issue in any case except for edmx file scenario.

Mystagogue answered 30/7, 2018 at 14:40 Comment(1)
Because SQL Server 2008 does not support FETCH and FETCH OFFSET requires orderby() skip() and take()Mystagogue
C
1

You need to use something like this :

var MinPageRank = (pageIndex - 1) * pageSize + 1;
var MaxPageRank = (pageIndex * pageSize);

var person = _context.Person.FromSql($"SELECT * FROM (SELECT [RANK] = ROW_NUMBER() OVER (ORDER BY Surname),* FROM Person) A WHERE A.[RANK] BETWEEN {MinPageRank} AND {MaxPageRank}").ToList();

IQueryable<Person> PersonIQ = from s in person.AsQueryable() select s;
Person = await PaginatedList<Person>.CreateAsync(PersonIQ .AsNoTracking(), pageIndex ?? 1, pageSize, sourceFull);
Commutation answered 19/4, 2018 at 7:17 Comment(1)
Why are you doing pageSize+ 1 ?Grams
S
0

Here, just set UseRowNumberForPaging() in ConfigureServices

services.AddDbContext<CallcContext>(options => 
options.UseSqlServer(Configuration.GetConnectionString("Connectionstring"),opt=> { opt.UseRowNumberForPaging(); }));
Sambo answered 13/11, 2018 at 8:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.