最近我们收到了来自两个客户的错误报告,其堆栈跟踪如下(我们的命名空间已被 ***** 替换):
[ArgumentException: Item has already been added. Key in dictionary: 'Boolean Single[Boolean](System.Collections.Generic.IEnumerable`1[System.Boolean])' Key being added: 'Boolean Single[Boolean](System.Collections.Generic.IEnumerable`1[System.Boolean])']
System.Reflection.CerHashtable`2.Insert(K[] keys, V[] values, Int32& count, K key, V value) +9600475
System.Reflection.CerHashtable`2.Preallocate(Int32 count) +307
System.RuntimeTypeCache.GetGenericMethodInfo(RuntimeMethodHandleInternal genericMethod) +299
System.RuntimeType.GetMethodBase(RuntimeType reflectedType, RuntimeMethodHandleInternal methodHandle) +543
System.RuntimeType.GetMethodBase(RuntimeType reflectedType, IRuntimeMethodInfo methodHandle) +25
System.Reflection.MethodBase.GetMethodFromHandle(RuntimeMethodHandle handle) +27
*****.Core.Repositories.Common.IsThereAnAuthorizedUserManager() +383
*****.Client.Host.WebLogin.Login.Page_Load(Object sender, EventArgs e) +334
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
System.Web.UI.Control.OnLoad(EventArgs e) +91
System.Web.UI.Control.LoadRecursive() +74
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2207
IsThereAnAuthorizedUserManager() 函数如下:
public bool IsThereAnAuthorizedUserManager()
{
return context.Users.Any(u => u.IsEnabled && u.DeletionDate == null && u.UserRoles.Any(ur => ur.Role.RoleOperations.Any(ro => ro.OperationType == (int)OperationType.ManageUsers)));
}
该语句输出的 SQL 如下:
exec sp_executesql N'SELECT
(CASE
WHEN EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[User] AS [t0]
WHERE ([t0].[IsEnabled] = 1) AND ([t0].[DeletionDate] IS NULL) AND (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[UserRole] AS [t1]
WHERE (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[Role] AS [t2], [dbo].[RoleOperation] AS [t3]
WHERE ([t3].[OperationType] = @p0) AND ([t2].[RoleID] = [t1].[RoleID]) AND ([t3].[RoleID] = [t2].[RoleID])
)) AND ([t1].[UserID] = [t0].[UserID])
))
) THEN 1
ELSE 0
END) AS [value]',N'@p0 int',@p0=102
.Any() 应该总是返回一个布尔结果,所以我不确定这将如何导致错误被抛出。我们还不能在测试中重现它,它似乎可以通过让用户重置 IIS 来解决。
以这种方式链接 .Any() 是否存在固有问题?或者也许我们做错了什么,我只是没有看到?我们当前的“修复”计划将用调用标量值 SQL 函数来替换语句,该函数将执行相同的逻辑而无需 .NET Framework 参与,但这似乎应该没必要。
作为参考,这似乎与这个问题非常相似:What does this key error mean when calling MethodInfo.MakeGenericMethod?