2010-03-12 8 views
5

Voici ma requête LINQ:OrderBy et Distinct à l'aide de LINQ-à-entités

(from o in entities.MyTable 
orderby o.MyColumn 
select o.MyColumn).Distinct(); 

Voici le résultat:

{"a", "c", "b", "d"} 

Voici le SQL généré:

SELECT 
[Distinct1].[MyColumn] AS [MyColumn] 
FROM (SELECT DISTINCT 
    [Extent1].[MyColumn] AS [MyColumn] 
    FROM [dbo].[MyTable] AS [Extent1] 
) AS [Distinct1] 

Est-ce un bug? Où est ma commande, putain?

Répondre

10

Vous devez trier aprèsDistinct car il ne vient pas avec aucune garantie quant à la préservation de l'ordre:

entities.MyTable.Select(o => o.MyColumn).Distinct().OrderBy(o => o); 
+0

Ce code ne compile pas. OrderBy donne l'erreur: 'Les arguments de type ne peuvent pas être déduits de l'utilisation. Essayez de spécifier les arguments de type explicitement. » –

+0

Oh je vois, il doit être' OrderBy (o => o) 'puisque par ce point les éléments ont déjà été sélectionnés (et nous travaillons avec un' IQueryable '). J'ai corrigé votre code et vous ai donné la coche - Merci! –

+0

@BlueRaja: Yep, raté ça. Merci pour la correction! –

1

Cette question porte sur les règles de LINQ to Objects: Preserving order with LINQ

Dans le base de données, encore moins d'opérations conservent l'ordre. Personne ne conserve l'ordre quand Distinct'ing (comme généralement un algorithme Hash est utilisé).

+0

Néanmoins, la requête 'SELECT DISTINCT ... ORDER BY ...' fonctionne comme vous le feriez dans SQL Server, et probablement dans d'autres SGBD - y a-t-il une raison pour laquelle la clause LINK orderby' est ignorée dans ce cas lors de la génération le SQL (il pourrait au moins lancer une erreur)? Je pense toujours que c'est un bug - la requête LINQ fonctionne correctement lorsqu'elle est utilisée sur un 'String []'. –

+0

Si vous vérifiez le plan de requête, il révélera que ORDER BY se produit après DISTINCT. En tant que tel, il y a des limitations strictes sur ce qui peut apparaître dans le ORDER BY. C'est juste un autre cas où la syntaxe de SQL cause la confusion. –

+0

Qu'est-ce que le "plan de requête" et comment puis-je l'afficher? J'ai obtenu cette requête ci-dessus en utilisant SQL Server 2008 Profiler, mais cela ne vous donne évidemment que la dernière requête. –