2016-06-28 10 views
3

私はListDocumentオブジェクトを持っています。 Documentクラスには多くのプロパティがありますが、ここでは2つのみがDocumentLinkIdUploadedOnDateです。特定のプロパティでDistinctを使用し、述語に基づいて保持するオブジェクトを選択するにはどうすればよいですか?

私がやりたいことは、リストをフィルターにかけることで、同じDocumentLinkIdの2つのDocumentオブジェクトがないことです。特定のDocumentLinkIdを持つDocumentオブジェクトが複数ある場合は、最新のUploadedOnDateを保持したいと考えています。

myDocumentsList.Distinct(d => d.DocumentLinkId).Max(d => d.UploadedOnDate); 

しかしDistinct()述語を取ることはありません。

私の初期の傾きは、このような何かをすることでした。 LINQでこれを行う方法はありますか?

+0

'DocumentLinkId'でグルーピングしてから、最大のUploadedOnDateを持つ各グループに1つずつ入れてみましょう – Nkosi

+0

Dictionary を使ってforループを書く方法は常にありますキャッシュ。おそらく最速で動作し、何かがうまくいかないとデバッグしやすくなるか、検索条件などを拡張したいと思うでしょう。 – Neolisk

答えて

8

あなたはできるDocumentLinkIdでグループ文書を、各グループのために、このような最新のUploadedOnDateで項目を選択します。

var result = myDocumentsList 
    .GroupBy(d => d.DocumentLinkId) 
    .Select(g => g.OrderByDescending(d => d.UploadedOnDate).First()) 
    .ToList(); 
+0

これは、例外をスローします。 'メソッド 'First'は最終的なクエリ操作としてのみ使用できます。このインスタンスでは 'FirstOrDefault'メソッドを代わりに使用することを検討してください。 – Legion

+0

LINQ to Entitiesを使用していますか? 'First'を' FirstOrDefault'に置き換えます。 –

+0

この場合、はい。 – Legion

1

あなたはthis questionに似DistinctByを使用することができます。

var query = people.DistinctBy(p => p.Id);あなたのケースのための

myDocumentsList.OrderByDescending(x => x.UploadedOnDate).ToList().DistinctBy(d => d.DocumentLinkId).Max(d => d.UploadedOnDate); 

それは次のようになります。

+0

これは、最初に異なる「DocumentLinkId」を持つ一連のドキュメントを選択します。それを選択すると、最新の「UploadedOnDate」を持つものを選択することも、選択しないこともできます。次に、そのセットを作成した後、最高の「UploadedOnDate」を持つ1つのドキュメントだけを選択します。したがって、別のセットを返さない。 1つのオブジェクトを返します。 –

+0

あなたは正しいです@ScottHannenリスト内のエントリを選択して、UploadedOnDateで最初に注文した後、DocumentLinkIdで別のものを選択するように答えを更新しました – meJustAndrew

1

IEqualityComparer<Document>の実装を定義できます。このシナリオはかなり正確に存在します。

public class DocumentLinkIdDocumentEqualityComparer : IEqualityComparer<Document> 
{ 
    public bool Equals(Document document1, Document document2) 
    { 
     return document1.DocumentLinkId == document2.DocumentLinkId; 
    } 
} 

次にあなたがこれを行うことができます:あなたが言っている

myDocumentsList.OrderByDescending(d => d.UploadedOnDate) 
    .Distinct(new DocumentLinkIdDocumentEqualityComparer()) 

(最初の最新の日付を持つように明確なリターン1を、それを注文し、これを編集する必要がありました。)

をこの1つの目的のためにDistinctの比較のために、このcomparerを使用し、同じDocumentLinkIdの2つの文書が等しいかのように動作させてください。

Documentを変更してEqualsを上書きする必要はありません。特に、この特定の等価比較はすべての場合に適用されるわけではないためです。これにより、特定のカスタム等価比較をいつ使用するかを指定できます。

+0

'return document1.DocumentLinkId == document2.DocumentLinkId;必要があります== – Legion

+0

はい、ありがとうございます。これは、回答エディタで直接コーディングするときに起こります。 –

関連する問題