LINQ to SQL does not generate ORDER BY when DISTIN

2019-01-14 16:52发布

问题:

The following basic LINQ to SQL statement does not result in the orderby working. As you can see in the T-SQL there is no orderby. Do you know why?

LINQ to SQL:

      var results = (from stats in db.t_harvest_statistics
                       orderby stats.unit_number
                       select stats.unit_number).Distinct().ToList();

Above Results in following TSQL

SELECT 
[Distinct1].[unit_number] AS [unit_number]
FROM ( SELECT DISTINCT 
[Extent1].[unit_number] AS [unit_number]
FROM [dbo].[t_harvest_statistics] AS [Extent1]
     )  AS [Distinct1]

回答1:

That is a limitation of SQL and Relational Algebra of where the ORDER BY is in relation to the DISTINCT.

The ORDER BY must be "further out" in the SQL (at the "top level") since it's a view operation. While one can write SQL that has the ORDER BY "further in", in relationship to a RA operation, it often results in Undefined Behavior (that sometimes works). In this light it makes sense that Linq2Sql is free to ignore the ORDER BY although, perhaps an exception would be better... it would be less subtle anyway ;-) (Actually, this same issue exists for any Linq provider that does not provide a "stricter" definition of Distinct.)

Remove the Distinct() and the Linq2Sql should once again generate the ORDER BY as expected. The solution is just to switch the order of operations so the ORDER BY is once again at the "top level".

This is covered by the article Use of Distinct and OrderBy in LINQ:

This behavior might appear strange. The problem is that the Distinct operator does not grant that it will maintain the original order of values. Applied to LINQ to SQL, this mean that a sort constraint can be ignored in the case of a query like queryA.

The solution is pretty s[i]mple: put the OrderBy operator after the Distinct one, like in the following queryB definition:

var queryB = 
    (from o in db.Orders
     select o.Employee.LastName)
    .Distinct().OrderBy( n => n );

Happy coding.



回答2:

I got same issue while sorting year from transaction table.

try this

 var results = (from stats in db.t_harvest_statistics
                       select stats.unit_number).Distinct().OrderBy(x =(Int16)x.unit_number).ToList();

after getting distinct value use orderby method