I have a very simple view that once I call this view with EF Core, I get the warning
The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results.
ALTER VIEW [dbo].[GridListings]
AS
SELECT l.*,
c.Name as city, r.code AS region, cn.code AS country, '' as url, '' as thumbnail
FROM [dbo].Listings l
INNER JOIN Cities c ON l.CityId = c.CityId
INNER JOIN Regions r ON r.RegionId = c.RegionId
INNER JOIN Countries cn ON cn.CountryId = r.CountryId
GO
```C#
var entities = await _context.GridListings
.Skip(offset)
.Take(request.PageSize)
.OrderBy(x => x.Createddate)
.ToListAsync();
Generated SQL (Sql Server Profiler)
```tsql
exec sp_executesql N'SELECT [t].[Address], [t].[AvailableDate], [t].[Baths], [t].[BedroomsAvailable], [t].[City], [t].[Country], [t].[Createddate], [t].[Description], [t].[ExpiryDate], [t].[Has24HourSecurity], [t].[HasAccessibleWashroomsInSuite], [t].[HasAirConditioning], [t].[HasAudioPrompts], [t].[HasBalcony], [t].[HasBarrierFreeEntranceAndRamp], [t].[HasBicyleParking], [t].[HasBrailleLabels], [t].[HasConcierge], [t].[HasDishwasher], [t].[HasElevator], [t].[HasFridge], [t].[HasGym], [t].[HasLandline], [t].[HasLaundryInBuilding], [t].[HasLaundryInUnit], [t].[HasPool], [t].[HasRentDeferral], [t].[HasStorageLocker], [t].[HasVisualAids], [t].[HasYard], [t].[ImportWebsite], [t].[ImportedContactInfo], [t].[ImportedEmail], [t].[ImportedPhoneNumber], [t].[ImportedReferenceNumber], [t].[ImportedSourceId], [t].[IsAutoGenerated], [t].[IsCableIncluded], [t].[IsDenIncluded], [t].[IsFurnished], [t].[IsHeatIncluded], [t].[IsHydroIncluded], [t].[IsInternetIncluded], [t].[IsPetFriendly], [t].[IsSmokingFriendly], [t].[IsWaterIncluded], [t].[IsWheelChairAccessible], [t].[LastUpdatedDate], [t].[LeaseDuration], [t].[ListingId], [t].[Location], [t].[NumberParkingSpotsIncluded], [t].[Price], [t].[Region], [t].[RentalsVirtualOptions], [t].[Sqft], [t].[Thumbnail], [t].[Title], [t].[UnitTypeId], [t].[Url]
FROM (
SELECT [g].[Address], [g].[AvailableDate], [g].[Baths], [g].[BedroomsAvailable], [g].[City], [g].[Country], [g].[Createddate], [g].[Description], [g].[ExpiryDate], [g].[Has24HourSecurity], [g].[HasAccessibleWashroomsInSuite], [g].[HasAirConditioning], [g].[HasAudioPrompts], [g].[HasBalcony], [g].[HasBarrierFreeEntranceAndRamp], [g].[HasBicyleParking], [g].[HasBrailleLabels], [g].[HasConcierge], [g].[HasDishwasher], [g].[HasElevator], [g].[HasFridge], [g].[HasGym], [g].[HasLandline], [g].[HasLaundryInBuilding], [g].[HasLaundryInUnit], [g].[HasPool], [g].[HasRentDeferral], [g].[HasStorageLocker], [g].[HasVisualAids], [g].[HasYard], [g].[ImportWebsite], [g].[ImportedContactInfo], [g].[ImportedEmail], [g].[ImportedPhoneNumber], [g].[ImportedReferenceNumber], [g].[ImportedSourceId], [g].[IsAutoGenerated], [g].[IsCableIncluded], [g].[IsDenIncluded], [g].[IsFurnished], [g].[IsHeatIncluded], [g].[IsHydroIncluded], [g].[IsInternetIncluded], [g].[IsPetFriendly], [g].[IsSmokingFriendly], [g].[IsWaterIncluded], [g].[IsWheelChairAccessible], [g].[LastUpdatedDate], [g].[LeaseDuration], [g].[ListingId], [g].[Location], [g].[NumberParkingSpotsIncluded], [g].[Price], [g].[Region], [g].[RentalsVirtualOptions], [g].[Sqft], [g].[Thumbnail], [g].[Title], [g].[UnitTypeId], [g].[Url]
FROM [GridListings] AS [g]
ORDER BY (SELECT 1)
OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY
) AS [t]
ORDER BY [t].[Createddate]',N'@__p_0 int,@__p_1 int',@__p_0=0,@__p_1=21
EF Core version: 5.0 RC2
The below code sample works well for me with the latest 5.0 builds. Can you please tweak it so that it fails, or submit a full, runnable code sample?
Attempted repro
```c#
await using var ctx = new GroupListingContext();
await ctx.Database.EnsureDeletedAsync();
await ctx.Database.EnsureCreatedAsync();
await ctx.Database.ExecuteSqlRawAsync(@"
CREATE VIEW [GridListings] AS
SELECT 1 AS [Id], 'SomeName' AS [Name], CAST ('2020-01-01' AS datetime2) AS [Createddate]");
var offset = 1;
var limit = 1;
_ = await ctx.GridListings
.Skip(offset)
.Take(limit)
.OrderBy(x => x.Createddate)
.ToListAsync();
public class GroupListingContext : DbContext
{
public DbSet
static ILoggerFactory ContextLoggerFactory
=> LoggerFactory.Create(b => b.AddConsole().AddFilter("", LogLevel.Information));
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer(...)
.EnableSensitiveDataLogging()
.UseLoggerFactory(ContextLoggerFactory);
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<GridListings>().ToView("GridListings");
}
}
public class GridListings
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Createddate { get; set; }
}
```
Warning happens before Skip/Take are applied before OrderBy. That means Skip/Take would be applied on non-deterministic ordering hence the warning. Please apply OrderBy before Skip/Take so you get consistent results.
Most helpful comment
Warning happens before Skip/Take are applied before OrderBy. That means Skip/Take would be applied on non-deterministic ordering hence the warning. Please apply OrderBy before Skip/Take so you get consistent results.