efcore: EFCore generate wrong sql when using UseRowNumberForPaging under concurrency requests
The SQL EFCore generated is as below.
exec sp_executesql N'SELECT [t0].[AutoID], [t0].[CreateTime], [t0].[HrefType], [t0].[HrefUrl], [t0].[IdentityID], [t0].[ImgUrl], [t0].[IsDel], [t0].[AutoID], [t0].[MenuType], [t0].[MerchID], [t0].[ModifyTime], [t0].[OrderAsc], [t0].[SchoolID], [t0].[Title], [t0].[CreateTime], [t0].[HrefType], [t0].[HrefUrl], [t0].[IdentityID], [t0].[ImgUrl], [t0].[IsDel], [t0].[MenuType], [t0].[MerchID], [t0].[ModifyTime], [t0].[OrderAsc], [t0].[SchoolID], [t0].[Title]
FROM (
SELECT [t].[AutoID], [t].[CreateTime], [t].[HrefType], [t].[HrefUrl], [t].[IdentityID], [t].[ImgUrl], [t].[IsDel], [t].[MenuType], [t].[MerchID], [t].[ModifyTime], [t].[OrderAsc], [t].[SchoolID], [t].[Title], ROW_NUMBER() OVER(ORDER BY [t].[OrderAsc]) AS [__RowNumber__]
FROM [T_Menu] AS [t]
WHERE (([t].[IsDel] = 0) AND ([t].[SchoolID] = @__schoolid_0)) AND ([t].[MenuType] = @__req_TypeID_1)
) AS [t0]
(
SELECT [t].[AutoID], [t].[CreateTime], [t].[HrefType], [t].[HrefUrl], [t].[IdentityID], [t].[ImgUrl], [t].[IsDel], [t].[MenuType], [t].[MerchID], [t].[ModifyTime], [t].[OrderAsc], [t].[SchoolID], [t].[Title], ROW_NUMBER() OVER(ORDER BY [t].[OrderAsc]) AS [__RowNumber__]
FROM [T_Menu] AS [t]
WHERE (([t].[IsDel] = 0) AND ([t].[SchoolID] = @__schoolid_0)) AND ([t].[MenuType] = @__req_TypeID_1)
) AS [t0]
WHERE (([t0].[__RowNumber__] > @__p_2) AND ([t0].[__RowNumber__] <= (@__p_2 + @__p_3))) AND ([t0].[__RowNumber__] <= (@__p_2 + @__p_3))',N'@__schoolid_0 uniqueidentifier,@__req_TypeID_1 int,@__p_2 int,@__p_3 int',@__schoolid_0='545E4B15-8427-41F8-95BD-421A9B1F2FCA',@__req_TypeID_1=1,@__p_2=0,@__p_3=20
In concurrency case, the issue can be reproduced with high change. The sql EFCore generated are different for same query and many of them are wrong.
Steps to reproduce
Create dbContext with codes below.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("Server=.;Database=mydatabase;user id=sa;password=123456;", options => options.UseRowNumberForPaging());
}
}
Start two threads and generate new DbContext and call query in each thread. The query is as below.
dbContext.Set<TMenu>().Where(t => t.SchoolId == Guid.Parse("545E4B15-8427-41F8-95BD-421A9B1F2FCA") && t.MenuType == typeId) .OrderBy(t => t.OrderAsc).Skip(0).Take(20);
Further technical details
EF Core version: (2.1.1) (The issue can be reproduced under 2.1.4) Database Provider: (e.g. Microsoft.EntityFrameworkCore.SqlServer) Operating system: Windows 10 Pro IDE: (e.g. Visual Studio 2017 15.7.4)
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 2
- Comments: 17 (7 by maintainers)
I believe I may be running into the same problem - in certain high volume cases we start getting errors like:
The multi-part identifier "t.__RowNumber__" could not be bound. The multi-part identifier "t.__RowNumber__" could not be bound.
They only get cleared by recycling the entire site.SQL 2008 R2 EF Core version: 2.2.3