Linq 组查询给出错误的结果
Linq group query gives wrong results
我在 C# 项目中使用 group by 子句执行 Linq 查询时遇到如下问题:
public class Stock {
public string Name {get; set;}
public List<int> Values {get; set;}
public float Price {get; set;}
}
// Stock collection
List<Stock> stocks = new List<Stock>()
{
new Stock(){Name="Prod1", Values=new List<int>{1, 2, 3, 0}, Price=5.0f,
new Stock(){Name="Prod1", Values=new List<int>{1, 2, 3, 0}, Price=5.0f,
new Stock(){Name="Prod11", Values=new List<int>{1, 0, 3, 1}, Price=8.0f,
new Stock(){Name="Prod11", Values=new List<int>{1, 0, 3, 1}, Price=8.0f,
new Stock(){Name="Prod18", Values=new List<int>{0, 0, 4, 1}, Price=4.5f,
new Stock(){Name="Prod20", Values=new List<int>{4, 0, 0, 2}, Price=9.9f,
new Stock(){Name="Prod20", Values=new List<int>{4, 0, 0, 2}, Price=9.9f,
new Stock(){Name="Prod29", Values=new List<int>{2, 1, 0, 1}, Price=7.2f,
};
var query = stocks.GroupBy(x => x, (x, g) => new { Count = g.Count(), Values = x}).ToList();
此查询给出了错误的分组结果。
为了 GroupBy
产生分组,您分组所依据的对象必须覆盖 GetHashCode
和 Equals
,或者您需要提供合适的相等比较器至 GroupBy
.
您的 Stock
没有覆盖 GetHashCode
/Equals
,并且您的 GroupBy
查询没有使用自定义相等比较器,因此您得到了意想不到的结果。
提供合适的覆盖将解决此问题:
public class Stock {
public string Name {get; set;}
public List<int> Values {get; set;}
public float Price {get; set;}
public override bool Equals(object obj) {
if (obj == this) return true;
var other = obj as Stock;
if (other == null) return false;
return Name.Equals(other.Name)
&& Price == other.Price
&& Values.SequenceEqual(other.Values);
}
public override int GetHashCode() {
return Name.GetHashCode()
+ Price.GetHashCode()
+ Values.Sum();
}
}
我在 C# 项目中使用 group by 子句执行 Linq 查询时遇到如下问题:
public class Stock {
public string Name {get; set;}
public List<int> Values {get; set;}
public float Price {get; set;}
}
// Stock collection
List<Stock> stocks = new List<Stock>()
{
new Stock(){Name="Prod1", Values=new List<int>{1, 2, 3, 0}, Price=5.0f,
new Stock(){Name="Prod1", Values=new List<int>{1, 2, 3, 0}, Price=5.0f,
new Stock(){Name="Prod11", Values=new List<int>{1, 0, 3, 1}, Price=8.0f,
new Stock(){Name="Prod11", Values=new List<int>{1, 0, 3, 1}, Price=8.0f,
new Stock(){Name="Prod18", Values=new List<int>{0, 0, 4, 1}, Price=4.5f,
new Stock(){Name="Prod20", Values=new List<int>{4, 0, 0, 2}, Price=9.9f,
new Stock(){Name="Prod20", Values=new List<int>{4, 0, 0, 2}, Price=9.9f,
new Stock(){Name="Prod29", Values=new List<int>{2, 1, 0, 1}, Price=7.2f,
};
var query = stocks.GroupBy(x => x, (x, g) => new { Count = g.Count(), Values = x}).ToList();
此查询给出了错误的分组结果。
为了 GroupBy
产生分组,您分组所依据的对象必须覆盖 GetHashCode
和 Equals
,或者您需要提供合适的相等比较器至 GroupBy
.
您的 Stock
没有覆盖 GetHashCode
/Equals
,并且您的 GroupBy
查询没有使用自定义相等比较器,因此您得到了意想不到的结果。
提供合适的覆盖将解决此问题:
public class Stock {
public string Name {get; set;}
public List<int> Values {get; set;}
public float Price {get; set;}
public override bool Equals(object obj) {
if (obj == this) return true;
var other = obj as Stock;
if (other == null) return false;
return Name.Equals(other.Name)
&& Price == other.Price
&& Values.SequenceEqual(other.Values);
}
public override int GetHashCode() {
return Name.GetHashCode()
+ Price.GetHashCode()
+ Values.Sum();
}
}