2008-10-10 17 views
10

Tengo una tabla, llamaremos al Users. Esta tabla tiene una sola clave principal definida en SQL Server - una autoincrement int ID.Excepción de LINQ extraño (Índice fuera de límites)

A veces, mis consultas LINQ contra esta tabla fallan con un error "Index was outside the range" - incluso el más simple de las consultas. La consulta en sí no usa ningún indexador.

Por ejemplo:

User = Users.Take(1); 

o

IEnumerable<Users> = Users.ToList(); 

Tanto de las consultas arrojó el mismo error. Usando el depurador Visualizer para ver la consulta generada, copio y pego la consulta en SQL y funciona bien. También hago clic en "ejecutar" en el visualizador y funciona bien. Pero ejecutar el código por sí solo arroja este error. No implemento ninguno de los métodos parciales en la clase, por lo que no está sucediendo nada allí. Si reinicio mi depurador, el problema desaparece, solo para volver atrás de nuevo al azar unas horas más tarde. Más críticamente, veo este error en mis registros de errores de la aplicación que se ejecuta en producción.

hago una tonelada de LINQ en mi aplicación, en contra de una docena de diferentes entidades en mi base de datos, pero sólo ver este problema en búsquedas similares a una entidad específica en mi mesa. Algunos google han sugerido que este problema podría estar relacionado con una relación incorrecta especificada entre mi modelo y otra entidad, pero no tengo ninguna relación con este objeto. Parece estar funcionando el 95% del tiempo, es solo el otro 5% que falla.

He eliminado por completo el objeto del diseñador y lo he vuelto a agregar desde un navegador de servidor "actualizado", y eso no solucionó el problema.

¿Alguna idea de lo que está pasando aquí?

Aquí está el mensaje de error y Seguimiento de la pila completo:

índice estaba fuera del rango. Debe ser no negativo y menor que el tamaño de de la colección. Nombre de parámetro: índice en System.Data.Linq.SqlClient.SqlProvider.Execute (consulta Expresión, QueryInfo QueryInfo, fábrica IObjectReaderFactory, Object [] parentArgs, userArgs [], ICompiledSubQuery [] SUBCONSULTAS objeto, objeto LASTRESULT) en System.Data.Linq.SqlClient.SqlProvider.ExecuteAll (consulta Expresión, QueryInfo [] queryInfos, fábrica IObjectReaderFactory, Object [] userArguments, ICompiledSubQuery [] sUBCONSULTAS) en System.Data.Linq.SqlClient.SqlProvider.System.Data .Linq.Provider.IProvider.Execute (Expresión consulta) en System.Data.Linq.Table 1.System.Linq.IQueryProvider.Execute[TResult](Expression expression) at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable 1 fuente, Expresión`1 predicado) en MyProject.FindUserByType (String typeId)

EDIT: Conforme a lo solicitado, a continuación es una copia del esquema de la tabla.

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] 

EDIT: El seguimiento de la pila muestra FirstOrDefault, pero duplica el error utilizando tanto Take() y ToList(). El seguimiento de la pila es idéntico entre todos estos, simplemente intercangnig FirstOrDefault/Take/ToList. El movimiento hacia abajo de la pila a SqlProvider.Execute es, de hecho, idéntico.

+0

No tengo idea de lo que está pasando, ¡pero es fascinante! Si todo lo demás falla, podría probar la lista del Proyecto General Linq: http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=123&SiteID=1 –

+0

Podría ser útil si pudiéramos ver la definición de la tabla. – KyleLanser

+0

(mssql -> Bases de datos -> the_db -> Tablas -> tabla_favoritos -> clic derecho -> Tabla de scripts como -> Crear a) – KyleLanser

Respuesta

0

La excepción se produce en una biblioteca del sistema y su historia me hace pensar que el problema no está en su código. ¿Ha cambiado el esquema recientemente? ¿Tu mapeo es correcto?

+0

El esquema no ha cambiado recientemente, aunque he tenido problemas durante bastante tiempo. Eliminé la tabla de culpable y la volví a agregar a través del navegador del servidor, sin éxito. – Matt

1

Yo diría que tienes un modelo -> base de datos no coinciden en alguna parte. Cuando me pongo tan desesperado como tú en situaciones como esta, usualmente enciendo VS.NET, creo una nueva aplicación de consola y reconstruyo la sección del DBML que hace referencia a la entidad de interés en esta consulta, y la vuelvo a ejecutar. Puede encontrar que en este tipo de aislamiento, la consulta funciona. ¿Personalizó alguna de las definiciones de su entidad completando métodos parciales, especialmente los que se activan en la creación?

-1

tiro en la oscuridad:

Usted está llamando MyProject.FindUserByType (String TypeId) en el interior de un cuerpo del bucle, utilizando la variable de bucle como el parámetro.

No utilice la variable de bucle directamente.

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

Si esto resulta ser el caso, voy a actualizar esta respuesta para explicar por qué el uso de variables de bucle es directamente una mala práctica (después de actualizar la pregunta para mostrar el bucle).

+0

Aquí es donde he visto el índice fuera de rango y LINQ to SQL antes de http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3782912&SiteID=1 –

+0

Hola David. De hecho, no estoy haciendo ningún bucle. Supongo que a lo que se refiere es que la ejecución diferida de la consulta puede dar como resultado que se use un valor diferente del previsto originalmente, ya que cambió durante el bucle. Sin embargo, es un punto interesante, ya que no se me había ocurrido. – Matt

5

Es casi seguro que esta no será la causa raíz de todos, pero encontré esta misma excepción en mi proyecto y encontré que la causa raíz era que se estaba lanzando una excepción durante la construcción de una clase de entidad. Curiosamente, la verdadera excepción es "perdida" y en su lugar se manifiesta como una excepción ArgumentOutOfRange que se origina en el iterador de la instrucción Linq que recupera el/los objeto/s.

Si recibe este error y ha introducido métodos OnCreated o OnLoaded en sus POCO, intente recorrer esos métodos.

+0

De hecho, es otro tipo de excepción oculta por esta "fuera de alcance". En mi caso, tuve el mismo problema y fue que el objeto que quería modificar estaba en un contexto no válido. – Hannish

0

Este problema se produce debido al objeto linq y los campos de la base de datos de esa tabla no son idénticos.

0

Tuve este problema también y lo resolví.

Ahora entiendo que el error fue el uso incorrecto del contexto de datos de Linq, pero tal vez mi experiencia todavía puede ayudar a otros a entender por qué obtienen este error.

Linq Data Context no está diseñado para ejecutarse simultáneamente. Por lo tanto, la creación de múltiples tareas ejecutando async no es ideal. Inspeccionar siguiente código de ejemplo para entender el problema:

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); 
} 

En mi caso, yo estaba pasando el contexto de datos como un parámetro en una pila de llamadas más tiempo, y llamar a los métodos asincrónicos lo largo del camino. Entonces no fue tan obvio como el ejemplo anterior. Pero tal vez esto puede ayudar a alguien más de todos modos :-)

Cuestiones relacionadas