2014-09-11 42 views
0

我有一個查詢,它是這樣定義的,我用它來生成一個JSON輸出。重點是,我已經應用了Distinct方法,但它仍然顯示重複的項目。例如,我有許多項目的值爲「未分類」,而我只需要其中的一個,其他值也一樣。這是我的查詢:如何從C#中的LINQ查詢獲取不同的項目?

var results = db.Users.OfType<Business>() 
       .Where(b => b.StateID == state && (term == null || b.Description.ToLower().Contains(term.ToLower()))) 
       .Distinct().Select(x => new { id = x.StateID, value = x.Description }).Take(5).ToList(); 

任何想法,如何解決它?我想我需要以某種方式特別應用不同的值。

+0

什麼字段是「未分類」?如果兩個記錄在該字段中具有相同的值,那麼您選擇哪個? – 2014-09-11 13:24:06

回答

4

我懷疑你需要切換你的DistinctSelect調用。 Distinct將比較您可能期望給出您的投影的更多字段,這可能意味着比較實際比較的字段以外的字段。首先調用Select將減少比較的字段的數量以生成不同的列表。

var results = db.Users.OfType<Business>() 
      .Where(b => b.StateID == state && (term == null || b.Description.ToLower().Contains(term.ToLower()))) 
      .Select(x => new { id = x.StateID, value = x.Description }) 
      .Distinct() 
      .Take(5) 
      .ToList(); 
+0

不知道爲什麼downvote,看起來像我合理的答案 – DavidG 2014-09-11 13:21:16

+1

「不同將比較你的類中的所有字段」只適用於已覆蓋'Equals'來比較所有字段的匿名類型和類型。我沒有倒下,但想明確表達這一點。 – 2014-09-11 13:22:53

+0

+1爲原創性,但同意@DStanley,它更好地編輯答案,以避免誤解 – 2014-09-11 13:25:14

0

Business類需要重寫object.Equalsobject.GetHashCode方法和Distinct方法之前實施IEquatable<T>將正常工作。

參見MSDN例子:Enumerable.Distinct Method (IEnumerable)

+1

這只是一種方式 - 你也可以實現一個'IEqualityComparer ',這可能是一個更好的選擇,因爲Overrriding Equals將應用於所有場景而不僅僅是這一場景。 – 2014-09-11 13:25:41

+0

這是Microsoft推薦的實際提供默認'IEqualityComparer'的方法。如果你需要運行一個不同的'Distinct()'從默認的'''IEqualityComparer'將會很好。鏈接中的註釋就在這裏。 :) – toadflakz 2014-09-12 07:38:14

+0

是的,但問題中的要求可能不一定需要是該類型的「默認」。這可能只是針對這種情況,在這種情況下,_non-default_'IEqualityComparer'會更合適。 – 2014-09-12 12:50:01

0

Distinct()返回序列中的不同元件通過使用默認的相等比較器來比較值。所以你應該創建BusinessEqualityComparer類應該實現IEqualityComparer接口

class BusinessEqualityComparer : IEqualityComparer<Business> 
{ 

    public bool Equals(Business b1, Business b2) 
    { 
     if (b1.ID == b2.ID) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 


    public int GetHashCode(Business business) 
    { 
     int hCode = business.ID^business.ID^business.ID; 
     return hCode.GetHashCode(); 
    } 
1

.NET沒有辦法知道要如何確定你的對象「平等」的方式。默認情況下,引用類型的相等性僅基於引用相等性,因此默認情況下,所有對象都是不同的。您可以提供custom equality comparerDistinct()。例如,如果你只是在一個.Name屬性比較以確定唯一性,它可能是這個樣子:

class BusinessComparer : IEqualityComparer<Business> 
{ 
    public bool Equals(Business x, Business y) 
    { 
     if (Object.ReferenceEquals(x, y)) 
      return true; 
     if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) 
      return false; 
     return x.Name == y.Name; 
    } 

    public int GetHashCode(Business business) 
    { 
     if (Object.ReferenceEquals(business, null)) 
      return 0; 
     int hashBusinessName = business.Name == null ? 0 : business.Name.GetHashCode(); 
     return hashProductName; 
    } 
} 

如果這種平等是核心業務邏輯,而不是僅僅在這個特殊的比較中,那麼你可能連在Business本身上實施EqualsGetHashCode,以便可以在其他地方使用相等比較。請注意,這可能是已經假定參照平等的現有代碼的重大改變。

0

.Distinct()如果不提供手動比較器,將使用處理類型的默認比較器,最終將使用Business類的.Equals().GetHashCode()

所以,除非你已經重寫了這些方法,否則.Distinct()將只刪除參考明確的重複項。

相關問題