2008-10-10 1 views
10

У меня есть таблица, мы назовем Users. В этой таблице есть один первичный ключ, определенный в SQL Server - автоинкремент int ID.Странное исключение LINQ (указатель за пределы)

Иногда мои запросы 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 [] подзапросов, объект lastResult) в System.Data.Linq.SqlClient.SqlProvider.ExecuteAll (Выражение запроса, QueryInfo [] queryInfos, IObjectReaderFactory завод, Object [] userArguments, ICompiledSubQuery [] подзапросов) в System.Data.Linq.SqlClient.SqlProvider.System.Data .Linq.Provider.IProvider.Execute (выражение query) в System.Data.Linq.Table 1.System.Linq.IQueryProvider.Execute[TResult](Expression expression) at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable 1 источник, Предикат Expression`1) в MyProject.FindUserByType (String typeId)

EDIT: В соответствии с запросом ниже приведена копия схемы таблицы.

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: трассировка стека показывает FirstOrDefault, но я продублировал ошибку, используя как Take() и ToList(). Трассировка стека идентична между всеми этими, просто interchangnig FirstOrDefault/Take/ToList. Переход вниз по стеку до SqlProvider.Execute на самом деле идентичен.

+0

Не знаю, что происходит, но увлекательно! Если все остальное не удается, вы можете попробовать общий список проектов Linq: http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=123&SiteID=1 – 2008-10-10 14:55:01

+0

Это может помочь, если мы сможем увидеть определение таблицы. – KyleLanser 2008-10-10 15:03:47

+0

(mssql -> Базы данных -> the_db -> Таблицы -> the_bad_table -> щелкните правой кнопкой мыши -> Таблица скриптов as -> Create To) – KyleLanser 2008-10-10 15:05:33

ответ

0

Исключение происходит в системной библиотеке, и ваша история заставляет меня думать, что проблема не в вашем коде. Недавно изменилась схема? Правильно ли ваше отображение?

1

Я бы сказал, что у вас есть некоторая несоответствие базы данных модели ->. Когда я получаю отчаяние, как вы в подобных ситуациях, я обычно запускаю VS.NET, создаю новое консольное приложение и перестраиваю раздел DBML, который ссылается на объект, представляющий интерес в этом запросе, и повторно запускается. Вы можете обнаружить, что в такой изоляции запрос работает. Вы настроили какие-либо определения своих сущностей, заполнив частичные методы, особенно те, которые срабатывают при создании?

-1

Выстрел в темноте:

Вы звоните MyProject.FindUserByType (String TypeID) внутри тела цикла, используя переменную цикла в качестве параметра.

Не используйте переменную цикла напрямую.

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

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

5

Это почти наверняка не будет основной причиной каждого, но я столкнулся с этим одним и тем же исключением в моем проекте и обнаружил, что основная причина заключалась в том, что при построении класса сущности было выбрано исключение. Как ни странно, истинное исключение «потеряно» и вместо этого проявляется как исключение ArgumentOutOfRange, возникающее на итераторе оператора Linq, которое извлекает объект/s.

Если вы получаете эту ошибку, и вы вводили методы OnCreated или OnLoaded в своих POCOs, попробуйте выполнить эти методы.

0

Эта проблема возникает из-за объектов linq и полей базы данных этой таблицы не идентичны.

0

У меня был этот вопрос, и он решил его.

Теперь я понимаю, что ошибка была неправильным использованием Linq Data Context, но, возможно, мой опыт может помочь другим понять, почему они получают эту ошибку.

Linq Data Context предназначен не для одновременного запуска. Поэтому создание нескольких задач, выполняющих async, не является идеальным. Проверьте следующий код, чтобы понять проблему:

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

В моем случае, я проходил контекст данных в качестве параметра в более стек вызовов и вызов методов асинхронных по пути. Так что это было не так очевидно, как приведенный выше пример. Но, может быть, это может помочь кому-то в любом случае :-)

Смежные вопросы