【问题标题】:Paging with Entity Framework 7 and SQL Server 2008使用 Entity Framework 7 和 SQL Server 2008 进行分页
【发布时间】:2015-05-01 21:34:58
【问题描述】:

我正在尝试使用分页(即 Entity Framework 7 中的 .Skip(...).Take(...)。它适用于 Microsoft SQL Server 2012 和 2014,但在 SQL Server 2008 上失败并出现以下错误:

System.Data.SqlClient.SqlException (0x80131904):“OFFSET”附近的语法不正确。 FETCH 语句中选项 NEXT 的使用无效。

我发现这是 EF 版本 6.1.2 (http://erikej.blogspot.com/2014/12/a-breaking-change-in-entity-framework.html) 中的一项重大更改。但修复方法是将 EDMX 文件设置 ProviderManifestToken 属性修改为“2008”。

问题在于 EF7 目前仅支持代码优先方案,因此没有任何 EDMX。问题是:如何使用 Entity Framework 7 配置 ASP.NET 5 网站以对 2012 年以前的 SQL Server 使用后备分页方法?

【问题讨论】:

  • 请查看问题 #1326 并添加您可能拥有的任何 cmets。

标签: asp.net-mvc sql-server-2008 paging entity-framework-core


【解决方案1】:

如果你使用 Edmx 文件,你必须使用 XML 编辑器打开 edmx 文件并更改

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

在第 7 行。

请查看此博客文章以获取更多信息: http://erikej.blogspot.com.tr/2014/12/a-breaking-change-in-entity-framework.html

【讨论】:

  • 谢谢。当我的 azure 数据库在本地数据库中获取时,同样的问题得到了解决。
  • 这为我节省了很多时间,值得更多关注。就我而言,我的开发环境是 SQL SERVER 2012,我的 QA 环境是 2008 R2。
  • 如果改成 2008 版,还能在 SQL Server 2012 上使用吗?
  • 已确认。它也适用于 SQL Server 2012。现在,我相信这个答案来自天堂!
  • 现在是 2019 年,这个修复仍然可以完美运行。现在我希望有人能从 2008 年开始更新我们的数据库……加油,DBA,你可以做到。 :)
【解决方案2】:

我自己在使用 EF 7 和 sql server 2008 时遇到了这个问题。幸运的是,在 EF 7 的最新 rc1 版本中,您可以使用 .UseRowNumberForPaging() 来解决这个问题,如下例所示:

services.AddEntityFramework()
  .AddSqlServer()
  .AddDbContext<YourDbContext>(options =>
     options.UseSqlServer(configuration["Data:DefaultConnection:ConnectionString"])
                    // this is needed unless you are on mssql 2012 or higher
                    .UseRowNumberForPaging()
                );

【讨论】:

  • 我这样做了,但我仍然遇到上述错误。
  • 在 RC 1 中不工作。Linq "Skip" 仍然尝试生成 OFFSET/FETCH NEXT 语法。
【解决方案3】:

它在 RC 1 中坏了。得等待获得 RC 2。

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

【讨论】:

  • 非常有用的链接。它帮助我解决了我的问题:options.UseSqlServer(connection, b => b.UseRowNumberForPaging());
  • 非常有帮助! useRowNumberForPaging() 解决了我的问题!
【解决方案4】:

EF Core 3.x 中的此功能 was removedUseRowNumberForPaging 被标记为已过时。但是,您可以改用 EfCore3.SqlServer2008Query 包。 Nuget 中有 2 个可用的包,一个用于 >= .NET 5.0,另一个用于 >= .NET 3.1

用法:

 services.AddDbContext<MyDbContext>(o => 
       o.UseSqlServer(Configuration.GetConnectionString("Default"))
        .ReplaceService<IQueryTranslationPostprocessorFactory, SqlServer2008QueryTranslationPostprocessorFactory>());

【讨论】:

    【解决方案5】:

    MyDbConnectionString 是来自任何来源的连接字符串

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

    UseRowNumberForPaging() 在任何情况下都解决了问题,除了 edmx 文件场景。

    【讨论】:

    • 因为 SQL Server 2008 不支持 FETCH 而 FETCH OFFSET 需要 orderby() skip() 和 take()
    【解决方案6】:

    你需要使用这样的东西:

    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);
    

    【讨论】:

    • 你为什么要做 pageSize+ 1 ?
    【解决方案7】:

    在这里,只需将UseRowNumberForPaging() 设置为ConfigureServices

    services.AddDbContext<CallcContext>(options => 
    options.UseSqlServer(Configuration.GetConnectionString("Connectionstring"),opt=> { opt.UseRowNumberForPaging(); }));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-02
      • 1970-01-01
      • 2019-05-31
      • 1970-01-01
      • 2011-01-15
      • 1970-01-01
      • 2015-09-29
      相关资源
      最近更新 更多