"System.ArgumentException: элемент с тем же ключом уже был добавлен."при попытке упорядочить запрос LINQ в памяти по ассоциации LINQ - PullRequest
3 голосов
/ 27 января 2011

Мы выполняем запрос к находящейся в памяти коллекции объектов данных LINQ. Проблема заключается в том, что мы упорядочиваем по столбцу в связанной таблице, записи которого еще не обязательно были загружены (отложенная загрузка:)

Dim oPkgProducts = _
From b In oBillPkg.BillProducts _
Where b.Successful.GetValueOrDefault(Common.X_INDETERMINATE) = _
    Common.X_INDETERMINATE _
Order By _
    b.ProductFromCache.ProvisionCodePriority.ProvisionPriority Ascending _
Select b

Мы зафиксировали следующую ошибку в производственном процессе, когда код попытался вызвать Count () для этого запроса:

System.ArgumentException: элемент с тот же ключ уже был добавлен. в System.ThrowHelper.ThrowArgumentException (ExceptionResource ресурс) в System.Collections.Generic.Dictionary 2.Insert(TKey key, TValue value, Boolean add) at System.Data.Linq.IdentityManager.StandardIdentityManager.SetCurrent(MetaType type) at System.Data.Linq.IdentityManager.StandardIdentityManager.Find(MetaType type, Object[] keyValues) at System.Data.Linq.CommonDataServices.GetCachedObject(MetaType type, Object[] keyValues) at System.Data.Linq.CommonDataServices.DeferredSourceFactory 1.TryGetCached Object (Object [] keyValues, T & cached) в System.Data.Linq.CommonDataServices.DeferredSourceFactory 1.Execute(Object instance) at System.Data.Linq.CommonDataServices.DeferredSourceFactory 1.DeferredSource.GetEnumerator () в System.Linq.Enumerable.SingleOrDefault [TSource] (IEnumerable 1 source) at System.Data.Linq.EntityRef 1.get_Entity () в PackageManagement.Product.get_ProvisionCodePriority () в C: \ Проекты \ библиотеки DLL \ DotNet35 \ PackageManagement \ PackageManagement.designer.vb: линия 14431 в ProvisionEngine.BillPackageProvision. Lambda $ _12 (BillProduct б) в C: \ Projects \ библиотеки DLL \ DotNet35 \ ProvisionEngine \ BillPackageProvision.vb: линия 394 в System.Linq.EnumerableSorter 2.ComputeKeys(TElement[] elements, Int32 count) at System.Linq.EnumerableSorter 1.Sort (TElement [] элементы, число Int32) в System.Linq.OrderedEnumerable 1.<GetEnumerator>d__0.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator 2.MoveNext () в System.Linq.Enumerable.Count [TSource] (IEnumerable`1 источник) в ProvisionEngine.BillPackageProvision.ProvisionPackage (BillPackage oBillPkg, Boolean bRecursiveCall) в C: \ Projects \ библиотеки DLL \ DotNet35 \ ProvisionEngine \ BillPackageProvision.vb: линия 397

Запутанная часть заключается в том, что когда операция была автоматически повторена через несколько секунд, она прошла успешно. И поскольку это единственное время, когда мы видели исключение (в остальное время код работает нормально), воспроизвести его будет нелегко.

Некоторые сведения: «ProductFromCache» - это вспомогательное свойство, которое использует технику Пита Монтгомери для реализации кеша LINQ to SQL . Код может быть переписан для использования свойства LINQ .Product по умолчанию. Я не думаю, что это является частью проблемы, потому что трассировка стека показывает, что исключение происходит внутри библиотек .NET System. Я думаю, что исключение происходит, когда вызывается свойство .ProvisionCodePriority - это возвращает запись из таблицы, связанной с таблицей продукта. Похоже, что LINQ пытается кэшировать результат этой отложенной загрузки в универсальном объекте Dictionary. Но по какой-то причине словарь уже содержит указанный ключ.

У кого-нибудь есть идея, почему это может происходить?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...