mainDictionary具有所有记录,所以我试图在ColorPriceDictionary上获得不同的记录,但是我有重复的记录
objProductFrontModel.ColorPriceDictionary =
mainDictionary.Select(m => new { m.Value.ColorId, m.Value.ColorText, m.Value.SizeId })
.Distinct()
.ToDictionary(m => m.ColorId, m => new ProductDetail { ItemText = m.ColorText, ItemId = m.SizeId });
.Distincit
从...开始似乎是多余的?词典中的所有键值都必须是唯一的,但是您不必选择不同的键值.您正在选择colorID,ColorText和SizeID的不同元组.在这些不同的元组中,明显有ColorID的某些重复值,这就是为什么会出错的原因.
我怀疑如果您从选择中删除SizeID,这将成功,因为ColorText似乎显然取决于SizeID.您的另一选择是将这些元组选择为可容纳ColorID的重复值(如列表)的数据结构.如果那行不通,我想您需要退后一步,想出一种其他方法来解决您要解决的任何问题.
Distinct
使用该equals
方法IEquatable
或IComparable
在类上确定不同性.
当您说时new { m.Value.ColorId, m.Value.ColorText, m.Value.SizeId }
,您正在创建带有三个未命名成员变量的匿名(未命名)类.equals
C#编译器为匿名类提供的默认实现是比较所有三个成员变量.因此,在您之后Distinct
,每个结果实例都具有三个变量的唯一组合,但不一定只是colorId
.
两种解决方案:
1)执行一个IComparator<T>
仅比较colorId
元素OR的自定义或
2)在定义的类上实现Equals
,然后在子句中使用它.GetHashCode
Element
Select
class MySelectorElement
{
string ColorId { get; set; }
string ColorText { get; set; }
string SizeId { get; set; }
override bool Equals(object other)
{
if (other is MySelectorElement)
{
return object.Equals(this.ColorId, ((MySelectorElement)other).ColorId);
}
else return false;
}
override int GetHashCode()
{
return this.ColorId.getHashCode();
}
}
//...
... Select(new MySelectorElement { ColorId = m.Value.ColorId, ... })
...
mainDictionary has all records so I am trying to get distinct records here on ColorPriceDictionary but I am having duplicate records
objProductFrontModel.ColorPriceDictionary =
mainDictionary.Select(m => new { m.Value.ColorId, m.Value.ColorText, m.Value.SizeId })
.Distinct()
.ToDictionary(m => m.ColorId, m => new ProductDetail { ItemText = m.ColorText, ItemId = m.SizeId });
.Distincit
seems redundant to begin with ... ?All key values in a dictionary must be distinct, but you aren't selecting distinct key values. You're selecting distinct tuples of colorID, ColorText, and SizeID. Within these distinct tuples, there are obvously some duplicate values for ColorID, which is why you're getting an error.
I suspect that if you remove SizeID from your selection, this will succeed, since ColorText seems obviously dependent on SizeID. Your other choice is to select these tuples into a data structure that tolerates duplicate values of ColorID, like a list. If that won't work, I'd say you need to take a step back and think about a different approach to whatever problem you're trying to solve.
Distinct
uses the equals
method, IEquatable
or IComparable
on the class to determine distinctness.
When you say new { m.Value.ColorId, m.Value.ColorText, m.Value.SizeId }
, you are creating an anonymous (unnamed) class with three unnamed member variables. The default equals
implementation provided by the C# compiler for anonymous classes is to compare all three member variables. So after your Distinct
, every result instance has a unique combination of the three variables, but not necessarily just colorId
.
Two solutions:
1) mplement a custom IComparator<T>
which compares just the colorId
of the element OR
2) Implement Equals
and GetHashCode
on a defined Element
class and then use that in the Select
clause.
class MySelectorElement
{
string ColorId { get; set; }
string ColorText { get; set; }
string SizeId { get; set; }
override bool Equals(object other)
{
if (other is MySelectorElement)
{
return object.Equals(this.ColorId, ((MySelectorElement)other).ColorId);
}
else return false;
}
override int GetHashCode()
{
return this.ColorId.getHashCode();
}
}
//...
... Select(new MySelectorElement { ColorId = m.Value.ColorId, ... })
...
本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文