私は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
_を書いたにもかかわらず、CustomerID
sは順序付けられません
この2番目のLINQクエリのSQLクエリは次のとおりです。
_SELECT DISTINCT [t0].[CustomerID]
FROM [dbo].[Orders] AS [t0]
_
ご覧のとおり、** ORDER BY
_句がありません。何故ですか?
Distinct()
メソッドを使用すると_ORDER BY
_句が消えるのはなぜですか?
予想される動作は、ソース内の一意のアイテムの順序付けされていないシーケンスを返すことです。
つまり、Distinct()
を使用すると、既存のIQueryableの順序は失われます。
あなたが望むのはおそらくこのようなものでしょう、OrderBy()afterDistinct()が実行された後;
var query = (from o in db.Orders
select new
{
o.CustomerID
}).Distinct().OrderBy(x => x.CustomerID);
メンバーを並べ替えて、Distinctの後にOrderByを配置してください。メソッドチェーンに戻す必要があります。
db.Orders.Select(o=>o.CustomerId).Distinct().OrderBy(id=>id);
とにかく、OrderByは一意のアイテムのみを操作し、すべてを操作するわけではないため、これはEnumerable Linqでクエリを設定するためのより効率的な方法です。また、 [〜#〜] msdn [〜#〜] によると、Enumerable.Distinctは要素の戻り順序を保証しないため、重複排除前の順序付けは無意味です。
個別を使用するため、返されるリストの順序は保証されません。 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);
詳しくは、この記事をご覧ください。
次の構成でORDER BYおよびDISTINCTをシミュレートできます。
var distinctItems = employees.GroupBy(x => x.EmpID).OrderBy(x => x).Select(y => y.First());