以下查询在第二个选择查询中返回重复结果。
国家/地区与联盟有0..1 to *
的关系。
联赛与用户联盟有1 to *
的关系。
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
但没有运气。
似乎要么必须使用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 :(得分:2)
您需要按CountryId
和Common_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 :(得分: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.League
和Map.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
,这可能是一种更可敬的方式。但是在我做之前有人想到了这一点,所以他赢得了荣耀。
答案 2 :(得分:0)
我会说您需要撤消查询。因此,不要从userLeagues开始,而是从国家/地区开始并包含子级联赛。