【问题标题】:Strange LINQ Exception (Index out of bounds)奇怪的 LINQ 异常(索引超出范围)
【发布时间】:2016-02-16 23:52:12
【问题描述】:

我有一张桌子,我们会打电话给Users。此表在 SQL Server 中定义了一个主键 - 自动增量 int ID

有时,我对该表的 LINQ 查询会失败并出现 "Index was outside the range" 错误 - 即使是最简单的查询也是如此。查询本身不使用任何索引器。

例如:

User = Users.Take(1);

IEnumerable<Users> = Users.ToList();

这两个查询都抛出了同样的错误。使用调试器 Visualizer 查看生成的查询 - 我将查询复制并粘贴到 SQL 中,它工作正常。我还在可视化器上单击“执行”,它工作正常。但是单独执行代码会引发此错误。我没有在类上实现任何部分方法,所以那里什么都没有发生。如果我重新启动调试器,问题就会消失,只是在几个小时后再次随机重新启动。更关键的是,我在生产中运行的应用程序的错误日志中看到了这个错误。

我在我的应用程序中针对数据库中的十几个不同实体执行了大量 LINQ,但我只在与表中特定实体相关的查询中看到此问题。一些谷歌搜索表明此问题可能与我的模型和另一个实体之间指定的不正确关系有关,但我与此对象没有 任何 关系。它似乎 95% 的时间都在工作,只有另外 5% 的时间失败了。

我已经从设计器中完全删除了该对象,并从“刷新”的服务器浏览器中重新添加了它,但这并没有解决问题。

有什么想法吗?

这是完整的错误消息和堆栈跟踪:

索引超出范围。必须是非负数且小于 集合。参数名称:索引处 System.Data.Linq.SqlClient.SqlProvider.Execute(表达式查询, QueryInfo queryInfo, IObjectReaderFactory 工厂, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object 最后一个结果)在 System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(表达式查询, QueryInfo[] queryInfos, IObjectReaderFactory 工厂, Object[] userArguments, ICompiledSubQuery[] subQueries) 在 System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(表达式 查询)在 System.Data.Linq.Table1.System.Linq.IQueryProvider.Execute[TResult](Expression expression) at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable1 来源, 表达式`1 谓词)在 MyProject.FindUserByType(String typeId)

编辑:根据要求,下面是表架构的副本。

CREATE TABLE [dbo].[Container](
[ID] [int] IDENTITY(1,1) NOT NULL,
[MarketCode] [varchar](max) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Description] [varchar](max) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Capacity] [int] NOT NULL,
[Volume] [float] NOT NULL
 CONSTRAINT [PK_Container] PRIMARY KEY CLUSTERED 
(
[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

编辑:堆栈跟踪显示FirstOrDefault,但我使用Take()ToList() 复制了错误。所有这些之间的堆栈跟踪都是相同的,只是相互交换FirstOrDefault/Take/ToList。在堆栈中向下移动到SqlProvider.Execute 实际上是相同的。

【问题讨论】:

  • 不知道发生了什么,但令人着迷!如果一切都失败了,你可以试试 General Linq 项目列表:forums.microsoft.com/MSDN/…
  • 如果我们能看到表定义可能会有所帮助。
  • (mssql -> 数据库 -> the_db -> 表 -> the_bad_table -> 右键单击​​ -> 将表编写为 -> 创建到)
  • Stacktrace 显示 FirstOrDefault,但代码示例未显示此方法。请使用 FirstOrDefault 显示代码或确认它未被调用。
  • 请同时粘贴此表(实体类型)的 DBML... 例如

标签: c# linq linq-to-sql


【解决方案1】:

这几乎肯定不会是每个人的根本原​​因,但我在我的项目中遇到了完全相同的异常 - 并发现根本原因是在构建实体类期间引发了异常。奇怪的是,真正的异常是“丢失”,而是表现为 ArgumentOutOfRange 异常,该异常源自检索对象的 Linq 语句的迭代器。

如果您收到此错误并且您在 POCO 上引入了 OnCreated 或 OnLoaded 方法,请尝试逐步执行这些方法。

【讨论】:

  • 确实,这是另一种被这种“超出范围”隐藏的异常。在我的情况下,我遇到了同样的问题,我想修改的对象是在一个无效的上下文中。
【解决方案2】:

我会说你在某个地方有一个模型 -> 数据库不匹配。当我在这种情况下像你一样绝望时,我通常会启动 VS.NET,创建一个新的控制台应用程序,然后重建引用此查询中感兴趣的实体的 DBML 部分,然后重新运行。您可能会发现,在这种隔离中,查询是有效的。您是否通过填写部分方法来自定义任何实体定义,尤其是那些在创建时触发的方法?

【讨论】:

    【解决方案3】:

    异常发生在系统库中,您的故事让我认为问题不在您的代码中。架构最近是否发生了变化?你的映射正确吗?

    【讨论】:

    • 架构最近没有改变,尽管我已经有一段时间了。我删除了罪魁祸首表并通过服务器浏览器重新添加它,但无济于事。
    【解决方案4】:

    由于该表的 linq 对象和数据库字段不相同,会出现此问题。

    【讨论】:

      【解决方案5】:

      我也遇到了这个问题并解决了。

      现在我明白错误是 Linq 数据上下文的错误使用,但也许我的经验仍然可以帮助其他人理解他们为什么会收到这个错误。

      Linq 数据上下文并不意味着同时运行。因此创建多个运行异步的任务并不理想。检查以下示例代码以了解问题:

      using(var ctx = new LinqDataContext())
      {
          List<Task> tasks = new List<Task>();
          for(int i=0;i<1000;i++)
          {
              var task = Task.Run(() => {
                  var customer = ctx.Customers.SingleOrDefault(o => o.Id == i);
                  customer.DoSomething();
              }
              tasks.Add(task);
          }
          Task.WaitAll(tasks);
      }
      

      在我的场景中,我将数据上下文作为参数传递到更长的调用堆栈中,并在此过程中调用异步方法。所以它不像上面的例子那么明显。但也许这无论如何都可以帮助其他人:-)

      【讨论】:

        猜你喜欢
        • 2015-03-31
        • 1970-01-01
        • 1970-01-01
        • 2011-03-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多