D
d-42
Hi,
I encountered a problem with a query of the following form:
var q2 = from p in Persons.OfType<Cust>
where p.AccountID == accid
where !(from x in PersonDistLocationMatch
where x.LocationID == locationid
select x.PersonID).Contains(p.PersonID)
select p;
The query itself works fine. It returns the customers belonging to
account accid that do not have an association to a particular
location.
The problem is during paging when I apply skip / take: e.g.:
q2 = q2.Skip(startrow).Take(maxrows)
// for example the function call executes
q2 = q2.Skip(0).Take(8) //for page 1
q2 = q2.Skip(8).Take(8) // for page 2 etc
The resulting sql queries linq generates have an unstable sort order.
For the first 'page' where skip is 0 it generates:
SELECT TOP (8) [t0].[personid] AS [PersonID], [t0].[namefirst] AS
[NameFirst], [t0].[namelast] AS [NameLast], [t0].[distaccountid] AS
[DistAccountID], [t0].[personrole] AS [Role]
FROM [dbo].[Persons] AS [t0]
WHERE (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[PersonDistLocationMatch] AS [t1]
WHERE ([t1].[personid] = [t0].[personid]) AND ([t1].
[distlocationid] = @p0)
))) AND ([t0].[distaccountid] = @p1) AND ([t0].[personrole] = @p2)
For subsequent pages where Skip is non-zero it generates:
SELECT [t2].[personrole] AS [Role], [t2].[personid] AS [PersonID],
[t2].[namefirst] AS [NameFirst], [t2].[namelast] AS [NameLast], [t2].
[distaccountid] AS [DistAccountID]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t0].[personid]) AS
[ROW_NUMBER], [t0].[personrole], [t0].[personid], [t0].[namefirst],
[t0].[namelast], [t0].[distaccountid]
FROM [dbo].[Persons] AS [t0]
WHERE (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[PersonDistLocationMatch] AS [t1]
WHERE ([t1].[personid] = [t0].[personid]) AND ([t1].
[distlocationid] = @p0)
))) AND ([t0].[distaccountid] = @p1) AND ([t0].[personrole] =
@p2)
) AS [t2]
WHERE [t2].[ROW_NUMBER] BETWEEN @p3 + 1 AND @p3 + @p4
ORDER BY [t2].[ROW_NUMBER]
The problem is that this query returns the rows in a different order
than the previous one. Which means that some of the records displayed
on the first page are displayed again on subsequent pages, and other
records are missing entirely.
I appear to have worked around it by defining the original query as:
var q2 = from p in Persons.OfType<Cust>
where p.AccountID == accid
where !(from x in PersonDistLocationMatch
where x.LocationID == locationid
select x.PersonID).Contains(p.PersonID)
orderby p.personid
select p;
which forces a sort on the query and stabilizes the row order.
Should it be considered a bug that skip / take do not generate stable
sort orders on their own? Or was it my error not to have enforced a
sort order?
-best regards
Dave
I encountered a problem with a query of the following form:
var q2 = from p in Persons.OfType<Cust>
where p.AccountID == accid
where !(from x in PersonDistLocationMatch
where x.LocationID == locationid
select x.PersonID).Contains(p.PersonID)
select p;
The query itself works fine. It returns the customers belonging to
account accid that do not have an association to a particular
location.
The problem is during paging when I apply skip / take: e.g.:
q2 = q2.Skip(startrow).Take(maxrows)
// for example the function call executes
q2 = q2.Skip(0).Take(8) //for page 1
q2 = q2.Skip(8).Take(8) // for page 2 etc
The resulting sql queries linq generates have an unstable sort order.
For the first 'page' where skip is 0 it generates:
SELECT TOP (8) [t0].[personid] AS [PersonID], [t0].[namefirst] AS
[NameFirst], [t0].[namelast] AS [NameLast], [t0].[distaccountid] AS
[DistAccountID], [t0].[personrole] AS [Role]
FROM [dbo].[Persons] AS [t0]
WHERE (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[PersonDistLocationMatch] AS [t1]
WHERE ([t1].[personid] = [t0].[personid]) AND ([t1].
[distlocationid] = @p0)
))) AND ([t0].[distaccountid] = @p1) AND ([t0].[personrole] = @p2)
For subsequent pages where Skip is non-zero it generates:
SELECT [t2].[personrole] AS [Role], [t2].[personid] AS [PersonID],
[t2].[namefirst] AS [NameFirst], [t2].[namelast] AS [NameLast], [t2].
[distaccountid] AS [DistAccountID]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t0].[personid]) AS
[ROW_NUMBER], [t0].[personrole], [t0].[personid], [t0].[namefirst],
[t0].[namelast], [t0].[distaccountid]
FROM [dbo].[Persons] AS [t0]
WHERE (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[PersonDistLocationMatch] AS [t1]
WHERE ([t1].[personid] = [t0].[personid]) AND ([t1].
[distlocationid] = @p0)
))) AND ([t0].[distaccountid] = @p1) AND ([t0].[personrole] =
@p2)
) AS [t2]
WHERE [t2].[ROW_NUMBER] BETWEEN @p3 + 1 AND @p3 + @p4
ORDER BY [t2].[ROW_NUMBER]
The problem is that this query returns the rows in a different order
than the previous one. Which means that some of the records displayed
on the first page are displayed again on subsequent pages, and other
records are missing entirely.
I appear to have worked around it by defining the original query as:
var q2 = from p in Persons.OfType<Cust>
where p.AccountID == accid
where !(from x in PersonDistLocationMatch
where x.LocationID == locationid
select x.PersonID).Contains(p.PersonID)
orderby p.personid
select p;
which forces a sort on the query and stabilizes the row order.
Should it be considered a bug that skip / take do not generate stable
sort orders on their own? Or was it my error not to have enforced a
sort order?
-best regards
Dave