2012-04-13 80 views
3

我有一個相當複雜的LINQ查詢,連接幾個表,並選擇一個新的匿名類型是三個IEnumerable的{Users, JobProviders, Jobs}。它返回一個IQueryable來維護延遲執行,從而消除this question中的DistintBy。Linq選擇不同的兩個屬性

其中一列是排名,我需要確保只選擇每個作業(另一列,許多作業將被選中)的排名最低的記錄。獨特不起作用,因爲排名顯然會使該行獨一無二。

我認爲group子句可能會有所幫助,但它會將返回類型更改爲IGrouping。我不完全瞭解小組是如何工作的,所以我可能是錯的,但它看起來不行。對於每項工作,有沒有什麼辦法可以說只採用最低級別?

let jobRank = JobProvider.Rank 
...where min(rank) 
+1

'Distinct'採用'IComparer'作爲可選參數。在'CompareTo'方法中提供你自己的不包含'Rank'的方法。 – Servy 2012-04-13 20:13:47

+0

我認爲在L2E中無法完成延期執行,因爲它無法將其轉換爲TSQL。這不是這種情況嗎? – Tyrsius 2012-04-13 20:29:59

回答

4

,因爲它令我生厭使用GROUPBY做一個不同的你可以用分組,爲多。你可以撥打FirstIGrouping以獲得一個項目,這實際上是一個獨特的。它會是這個樣子:

var distinctItems = data.GroupBy(item => new{ 
    //include all of the properties that you want to 
    //affect the distinct-ness of the query 
    item.Property1 
    item.Property2 
    item.Property3 
}) 
.Select(group => group.Key); 
//if it's important that you have the low rank use the one below. 
// if you don't care use the line above 
//.Select(group => group.Min(item => item.Rank)); 
+0

我很確定這不會轉換爲SQL。它將以一個linq-to-objects查詢的方式靜靜地運行。如果是這樣,性能非常糟糕。 – usr 2012-04-13 21:10:20

+0

@usr爲什麼不會轉換爲SQL?如果你嘗試了它,但它不能,我會相信你,但我知道至少可以想象它會起作用(取決於提供者)。 groupby不是讓我擔心的事情。 'select-> first'有一點牽扯,所以翻譯它可能會更困難。即使是這樣,更難的工作是groupby。 – Servy 2012-04-13 21:14:15

+0

這是什麼讓你畏縮,它看起來像一個乾淨的解決方案。特別是考慮使用自定義IEqualityComparer的替代方案需要一個全新的類 – Tyrsius 2012-04-13 21:14:16

2

好這裏的解決方案:

LINQ's Distinct() on a particular property

你需要的是一個 「明顯的,通過」 有效。我不相信它是LINQ的一部分,儘管它很容易編寫:

What you need is a "distinct-by" effectively. I don't believe it's part of LINQ as it stands, although it's fairly easy to write: 

public static IEnumerable<TSource> DistinctBy<TSource, TKey> 
    (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) 
{ 
    HashSet<TKey> seenKeys = new HashSet<TKey>(); 
    foreach (TSource element in source) 
    { 
     if (seenKeys.Add(keySelector(element))) 
     { 
      yield return element; 
     } 
    } 
} 
+1

你不回答OP,問的問題。 – nawfal 2013-05-15 19:43:40