2017-02-28 234 views
0

以下查詢返回第二個select查詢中的重複結果。Linq查詢返回重複結果

國家有0..1 to *與聯賽的關係。

聯盟有1 to *與userLeagues的關係。

return from ul in userLeagues 
      select new Map.Country 
      { 
       id = ul.Country.CountryId, 
       name = ul.Country.Common_Name, 
       leagues = userLeagues.Where(x => x.CountryId.Value == ul.CountryId.Value) 
            .Select(x => new Map.League 
            { 
             id = x.LeagueID, 
             name = x.leagueNameEN, 
            }) 

      }; 

我試過用Distinct沒有運氣。 看來,無論是我必須使用不同的或GROUPBY countryId

輸出是如

[ 
    { 
    "id": 1, 
    "name": "Europe", 
    "leagues": [ 
     { 
     "id": 2, 
     "name": "Champions League", 
     }, 
     { 
     "id": 3, 
     "name": "Europa league", 
     } 
    ] 
    }, 
    { 
    "id": 1, 
    "name": "Europe", 
    "leagues": [ 
     { 
     "id": 2, 
     "name": "Champions League", 
     }, 
     { 
     "id": 3, 
     "name": "Europa league", 
     } 
    ] 
    } 
] 
+0

也許嘗試加入'.ToList()'你要指定爲'leagues'查詢結束。但是,「重複」是什麼意思?你是說每個國家都得到所有的用戶聯盟,或者每個國家都獲得屬於最後一個國家的所有用戶聯盟,或者是什麼? –

+0

重複在哪些列/屬性? –

+0

你不能使用group by來刪除重複的結果嗎? –

回答

2

你需要它組由CountryIdCommon_Name得到預期的結果:

var result = from ul in userLeagues 
      group ul by new { ul.Country.CountryId, ul.Country.Common_Name } into g 
      select new Map.Country 
      { 
       id = g.Key.CountryId, 
       name = g.Key.Common_Name, 
       leagues = g.Select(x => new Map.League 
       { 
        id = x.LeagueID, 
        name = x.leagueNameEN, 
       }) 
      }; 
1

想想你在做什麼:對於每一個聯賽userLeagues,你要創建一個Map.Country爲聯盟所屬的國家。如果三個聯賽在法國,那就是三個法國人。法國是一個美好的國家,但我們不要過分溺愛。

相反,你想從一個明確的國家名單開始。對於每一個,創建一個Map.Country,併爲該Map.Country列出應該屬於它的聯賽列表。

首先,讓我們Country實施IEquatable<Country>Distinct用途:

public class Country : IEquatable<Country> 
{ 
    public bool Equals(Country other) 
    { 
     return other.CountryID == CountryID; 
    } 

其次,要與國家的不同的名單開始,然後用聯賽進行填充。

var q = 
    from ctry in userLeagues.Select(ul => ul.Country).Distinct() 
    select new 
    { 
     id = ctry.CountryID, 
     name = ctry.Common_Name, 
     leagues = userLeagues.Where(x => x.Country == ctry) 
          .Select(x => new 
          { 
           id = x.LeagueID, 
           name = x.leagueNameEn 
          }).ToList() 
    }; 

我沒有重新創建Map.LeagueMap.Country班,我只是用匿名的對象,我離開它,那是因爲這個代碼肯定工程只是因爲它是。但填寫你的類名是微不足道的。

如果它不實用,使Country實施IEquatable<T>,只寫一個快速的相等比較和使用:

public class CountryComparer : IEqualityComparer<Country> 
{ 
    public bool Equals(Country x, Country y) 
    { 
     return x.CountryID == y.CountryID; 
    } 

    public int GetHashCode(Country obj) 
    { 
     return obj.CountryID.GetHashCode(); 
    } 
} 

...像這樣:

var cc = new CountryComparer(); 

var q = 
    from ctry in userLeagues.Select(ul => ul.Country).Distinct(cc) 
    select new 
    { 
     id = ctry.CountryID, 
     name = ctry.Common_Name, 
     leagues = userLeagues.Where(x => cc.Equals(x.Country, ctry)) 
          .Select(x => new 
          { 
           id = x.LeagueID, 
           name = x.leagueNameEn 
          }).ToList() 
    }; 

這是邏輯上等同於一個GroupBy,這可能是一個更可敬的方法來做到這一點。但有人在我做之前就想到了這一點,所以他贏得了榮譽。

0

我會說你需要扭轉你的查詢。因此,不要從用戶聯盟開始,而應從國家開始幷包含兒童聯賽。