2011-05-12 187 views
10

鮮明的考慮:的LINQ在特定領域

var s = (from p in operatorList      
    select p.ID, p.Name,p.Phone) 

如何將返回僅基於ID的不重複的記錄?

+2

這Q是很像[刪除重複的基於列的值-LINQ( http://stackoverflow.com/q/3446442/590956) – Sam

回答

14

您可以編寫一個IEqualityComparer比較ID值並將其傳遞到overloaded Queryable.Distinct method,但由於這是LINQ to SQL,因此它不會在數據庫上受支持。您必須添加對AsEnumerable method的調用才能使其正常工作,但這不建議用於大量數據,因爲您會將數據帶到客戶端。如果你決定走這條路,你將最終獲得類似的查詢:

var query = dc.Operators.AsEnumerable().Distinct(new OperatorEqualityComparer()); 

另一種選擇,這使數據庫做的工作,就是按ID並採取各組中的第一項:

var query = from p in dc.Operators 
      group p by p.ID into groups 
      select groups.First(); 
7

如果你想添加要做到這一點作爲一個擴展方法的能力,這裏有一個叫做DistinctBy方法,這需要在源和的KeySelectors作爲參數,並返回不同的項目組。它與Ahmad的第二個查詢完全相同,但看起來更加漂亮。

C#
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
           this IEnumerable<TSource> source, 
           Func<TSource, TKey> keySelector) 
{ 
    return source.GroupBy(keySelector).Select(i => i.First()); 
} 
VB
<Extension()> 
Public Function DistinctBy(Of TSource, TKey)(
        ByVal source As IEnumerable(Of TSource), 
        ByVal keySelector As Func(Of TSource, TKey)) 
        As IEnumerable(Of TSource) 

    Return source.GroupBy(keySelector).Select(Function(i) i.First()) 
End Function 

然後調用這樣的:

var s = (from p in operatorList.DistinctBy(x => x.ID)      
     select p.ID, p.Name, p.Phone)