我在生产环境的错误日志中收到了这个异常:
System.ArgumentException: An item with the same key has already been added
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
该代码在所有其他环境中以及单元测试期间都运行良好。我猜测存在某种多线程问题,但我不知道它会是什么。我假设我会得到某种 Collection Modified 异常,而不是重复键异常。
这不是确切的,而是一个关于代码实际做什么的更简单的示例:
编辑1
我重新定义了它的调用方式以及信息的存储方式,希望能回答评论中的一些常见问题...
public LotInfo CallSite(){
return new LotInfo(new CarLot());
}
public class LotInfo {
private Dictionary<int,int> SumOfMileageByYear { get; set; }
public LotInfo(CarLot carLot)
{
SumOfMileageByYear = (from c in carLot.Cars
group c by c.Year into carsByYear
select new { Year = carsByYear.Key, Sum = carsByYear.Sum(c => c.Mileage) })
.ToDictionary(c => c.Year, c => c.Sum);
}
}
public class CarLot
{
private IEnumerable<Car> _cars;
public IEnumerable<Car> Cars
{
get
{
return _cars ?? (_cars = new List<Car>()
{
new Car(1984, "Dodge", "Rampage", 40696),
new Car(2006, "Volkswagen", "Jetta", 42714),
new Car(2009, "Nissan", "Versa", 53934),
new Car(2005, "Lincoln", "Town Car", 62381),
new Car(2008, "Ford", "Focus", 66072),
new Car(2007, "Toyota", "Yaris", 68163),
new Car(2009, "Hyundai", "Sonata", 71279),
new Car(2006, "Ford", "F150", 73463),
new Car(2005, "Mazda", "RX-8", 75000),
new Car(2007, "Volkswagen", "Passat", 78490),
new Car(2010, "Nissan", "Cube", 78505),
new Car(2008, "Kia", "Sedona", 80874),
new Car(2006, "Mitsubishi", "Eclipse", 81186),
new Car(2008, "Ford", "Taurus", 83332),
new Car(2008, "Pontiac", "G6", 85842),
});
}
set
{
_cars = value;
}
}
}
public class Car
{
public int Year { get; set; }
public int Mileage { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public Car(int year, string make, string model, int mileage)
{
Year = year;
Make = make;
Model = model;
Mileage = mileage;
}
}
调用Example
方法,传入一个新的CarLot
实例,检索属性Cars
,这是延迟加载的,但是返回一个隐式转换为 IEnumerable 的列表。然后 Group By 方法应该返回一个键及其值。 ToDictionary()
调用启动了所有延迟执行。
Group By Linq 查询如何在不引发异常的情况下生成重复键,从而导致 ToDicitionary 调用失败?
编辑2
这是零上下文的实际代码,示例基本上提供与实际代码相同的上下文,更清晰。我添加了它以防万一我错过了什么。
RepLeadCapTotalByRepRank = (from c in info.RepLeadCaps
group c by c.RepRank.Value into byRepTier
select new { RepTier = byRepTier.Key, Sum = byRepTier.Sum(v => v.Cap ?? 0) })
.ToDictionary(k => k.RepTier, v => v.Sum);
我是一名优秀的程序员,十分优秀!