我正在尝试使用分页(即 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-writing-change-in-entity-framework.html)。但修复方法是修改 EDMX 文件,将 ProviderManifestToken 属性设置为“2008”。
问题是 EF7 目前仅支持代码优先场景,因此没有任何 EDMX。问题是:如何使用 Entity Framework 7 配置 ASP.NET 5 网站,以便对 2012 年之前的 SQL Server 使用回退分页方法?
如果您使用 Edmx 文件,则必须使用 XML 编辑器打开 edmx 文件并更改
ProviderManifestToken="2012" ==> ProviderManifestToken="2008"
第 7 行。
请查看此博文以了解更多信息: http://erikej.blogspot.com.tr/2014/12/a-writing-change-in-entity-framework.html
我自己在使用 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()
);
此功能在 EF Core 3.x 中已删除,
UseRowNumberForPaging
被标记为已过时。但是,您可以使用 EfCore3.SqlServer2008Query
包代替。 Nuget 中有 2 个可用的软件包,一个适用于 >= .NET 5.0,另一个适用于 >= .NET 3.1
用途:
services.AddDbContext<MyDbContext>(o =>
o.UseSqlServer(Configuration.GetConnectionString("Default"))
.ReplaceService<IQueryTranslationPostprocessorFactory, SqlServer2008QueryTranslationPostprocessorFactory>());
RC 1 坏了。得等 RC 2。
MyDbConnectionString是来自任何来源的连接字符串
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(_config["MyDbConnectionString"],
options=>
{
options.UseRowNumberForPaging();
});
}
UseRowNumberForPaging()
解决了除 edmx 文件场景之外的任何情况下的问题。
你需要使用这样的东西:
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);
这里,只需将
UseRowNumberForPaging()
设置为ConfigureServices
即可
services.AddDbContext<CallcContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("Connectionstring"),opt=> { opt.UseRowNumberForPaging(); }));