奇怪的LINQexception(索引超出范围)

我有一张桌子,我们会打电话给Users 。 此表具有在SQL Server中定义的单个主键 – autoincrement int ID

有时,我对这个表的LINQ查询失败, "Index was outside the range"错误 – 即使是最简单的查询。 查询本身不使用任何索引器。

例如:

 User = Users.Take(1); 

要么

 IEnumerable = Users.ToList(); 

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

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

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

有什么想法在这里发生了什么?

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

指数超出范围。 必须是非负数且小于集合的大小。 参数名称:System.Data.Linq的System.Data.Linq.SqlClient.SqlProvider.Execute(表达式查询,QueryInfo queryInfo,IObjectReaderFactory工厂,Object [] parentArgs,Object [] userArgs,ICompiledSubQuery [] subQueries,Object lastResult)的索引System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute中的.SqlClient.SqlProvider.ExecuteAll(Expression query,QueryInfo [] queryInfos,IObjectReaderFactory factory,Object [] userArguments,ICompiledSubQuery [] subQueries) (表达式查询)System.Data.Linq.Table 1.System.Linq.IQueryProvider.Execute[TResult](Expression expression) at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable 1 source,Expression`1谓词)at at 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()复制错误。 堆栈跟踪在所有这些之间是相同的,只是interchangnig FirstOrDefault/Take/ToList 。 从堆栈向下移动到SqlProvider.Execute实际上是相同的。

这几乎肯定不会是每个人的根本原​​因,但我在我的项目中遇到了这个完全相同的exception – 并且发现根本原因是在构造实体类期间抛出exception。 奇怪的是,真正的exception是“丢失”,而是表现为一个ArgumentOutOfRangeexception,它起源于检索对象的Linq语句的迭代器。

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

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

系统库中出现exception,您的故事让我觉得问题不在您的代码中。 架构最近有变化吗? 你的映射是否正确?

由于该表的linq对象和数据库字段不相同而发生此问题。

我也有这个问题并解决了它。

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

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

 using(var ctx = new LinqDataContext()) { List tasks = new List(); 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); } 

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

在黑暗中拍摄:

您使用循环变量作为参数在循环体内调用MyProject.FindUserByType(String typeId)。

不要直接使用循环变量。

 foreach(string s in myTypeList) { //GetUserByType(s); //Ooo, bad string tempstring = s; GetUserByType(tempstring); } 

如果情况确实如此,我将更新这个答案来解释为什么直接使用循环变量是一种不好的做法(更新问题后显示循环)。