web-dev-qa-db-ja.com

DISTINCT()およびORDERBYの問題

私はLINQ-to-SQLについて学習しており、奇妙なことが起こるまですべてが順調でした。

distinctの例を作ろうとしたので、Northwind dabataseを使用して次のクエリを記述しました。

_var query = 
    from o in db.Orders
    orderby o.CustomerID
    select new
    {
        o.CustomerID
    };
_

queryに格納されているクエリのLINQ-to-SQLによって生成されたSQLを出力すると、次のようになります。

_SELECT [t0].[CustomerID]
FROM [dbo].[Orders] AS [t0]
ORDER BY [t0].[CustomerID]
_

したがって、通常どおり、クエリはCustomerIDテーブルの各OrderのすべてのOrdersをアルファベット順に並べます。

だが!次のようにDistinct()メソッドを使用すると、

_var query = (
    from o in db.Orders
    orderby o.CustomerID
    select new
    {
        o.CustomerID
    }).Distinct();
_

クエリはDistinct句の期待される結果をもたらしますが、_orderby o.CustomerID_を書いたにもかかわらず、CustomerIDsは順序付けられません

この2番目のLINQクエリのSQLクエリは次のとおりです。

_SELECT DISTINCT [t0].[CustomerID]
FROM [dbo].[Orders] AS [t0]
_

ご覧のとおり、** ORDER BY_句がありません。何故ですか?

Distinct()メソッドを使用すると_ORDER BY_句が消えるのはなぜですか?

23
Dante

Queryable.Distinctのドキュメントから ;

予想される動作は、ソース内の一意のアイテムの順序付けされていないシーケンスを返すことです。

つまり、Distinct()を使用すると、既存のIQueryableの順序は失われます。

あなたが望むのはおそらくこのようなものでしょう、OrderBy()afterDistinct()が実行された後;

var query = (from o in db.Orders
             select new
             {
                 o.CustomerID
             }).Distinct().OrderBy(x => x.CustomerID);
40

メンバーを並べ替えて、Distinctの後にOrderByを配置してください。メソッドチェーンに戻す必要があります。

db.Orders.Select(o=>o.CustomerId).Distinct().OrderBy(id=>id);

とにかく、OrderByは一意のアイテムのみを操作し、すべてを操作するわけではないため、これはEnumerable Linqでクエリを設定するためのより効率的な方法です。また、 [〜#〜] msdn [〜#〜] によると、Enumerable.Distinctは要素の戻り順序を保証しないため、重複排除前の順序付けは無意味です。

15
KeithS

個別を使用するため、返されるリストの順序は保証されません。 LinqToSqlはこれを認識するのに十分スマートなので、無視します。

Distinctの後で注文すると、すべてが思い通りに行われます。

var query = (from o in db.Orders
             select new
             {
                 o.CustomerID
             }).Distinct().OrderBy(o => o.CustomerID);

または

var query = db.Orders.Select(o => o.CustomerID).Distinct().OrderBy(o => o.CustomerID);

詳しくは、この記事をご覧ください。

http://programminglinq.com/blogs/marcorusso/archive/2008/07/20/use-of-distinct-and-orderby-in-linq.aspx

3
Jaime Torres

次の構成でORDER BYおよびDISTINCTをシミュレートできます。

var distinctItems = employees.GroupBy(x => x.EmpID).OrderBy(x => x).Select(y => y.First());
1
Ratamahatta