Correct behavior of OrderBy

2019-07-03 12:25发布

问题:

I have encountered something that puzzles me and I would like to see your opinion on the matter. It turns out that linq to sql and entity framework threats consecutive order by's differently.

The following code is used just for example and I am not claiming it has any sense at all:

Linq to sql:

DataClasses1DataContext db = new DataClasses1DataContext();
        var result = (from c in db.Products
                      orderby c.ProductName
                      orderby c.UnitPrice
                      orderby c.UnitsOnOrder
                      select c).ToList();

What it generats on the server side:

SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued]
FROM [dbo].[Products] AS [t0]
ORDER BY [t0].[UnitsOnOrder], [t0].[UnitPrice], [t0].[ProductName]

The same test with Entity Framework generates this:

    SELECT 
[Extent1].[ProductID] AS [ProductID], 
[Extent1].[ProductName] AS [ProductName], 
[Extent1].[SupplierID] AS [SupplierID], 
[Extent1].[CategoryID] AS [CategoryID], 
[Extent1].[QuantityPerUnit] AS [QuantityPerUnit], 
[Extent1].[UnitPrice] AS [UnitPrice], 
[Extent1].[UnitsInStock] AS [UnitsInStock], 
[Extent1].[UnitsOnOrder] AS [UnitsOnOrder], 
[Extent1].[ReorderLevel] AS [ReorderLevel], 
[Extent1].[Discontinued] AS [Discontinued]
FROM [dbo].[Products] AS [Extent1]
ORDER BY [Extent1].[UnitsOnOrder] ASC

As you can see Linq To Sql adds all the requested order by's where the last one has the highest priority (which in my opinion is correct). On the other hand entity framework respects only the last order by and disregards all the others.

Now I know there is an order by then by clause that can be used but I am just wondering which behavior is more correct. Also as far as I remember the query extenders used in asp are working with a separate order by which if applied on a query generated from a different data source will not work correctly (according to the above example one of the order by's will be omitted)

回答1:

My opinion is that EF is correct. I don't know why L2S would do what you're describing - in my opinion, if you add an OrderBy clause instead of using ThenBy, it should overwrite any existing OrderBys.

When you're working with Linq-To-Objects, you should see OrderBy replace any previous ones, so it makes more sense to me to have the data-driven LINQ act the same.

If the behavior changed the way you're describing, then it seems that Microsoft agrees, since EF was designed to replace L2S.



回答2:

What i've learned is that the order by is written like this:

DataClasses1DataContext db = new DataClasses1DataContext();
        var result = (from c in db.Products
                      orderby c.UnitsOnOrder, c.UnitPrice, c.ProductName
                      select c).ToList();

And like that you can see the order clear to every one.