У меня есть сайт ASP.NET, который уже давно работает отлично, в последнее время ничего не изменилось. С часа до следующего я начал получать исключение IndexOutOfRangeException в строке, где я выполняю запрос LINQ следующим образом:
var form = SqlDB.GetTable<ORMB.Form, CDB>()
.Where(f => f.FormID == formID)
.Single();
ORMB.Form - это объект POCO с атрибутами LINQ to SQL, сопоставляющими его с таблицей MSSQL (сопоставление подтверждено как правильное). Трассировка стека выглядит следующим образом:
System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Collections.Generic.List`1.Add(T item)
at System.Data.Linq.SqlClient.SqlConnectionManager.UseConnection(IConnectionUser user)
at System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult)
at System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries)
at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
at System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.Single[TSource](IQueryable`1 source)
at GetForm.Page_Load(Object sender, EventArgs e)
Отражение System.Collections.Generic.List.Add показывает следующий код:
public void Add(T item)
{
if (this._size == this._items.Length)
{
this.EnsureCapacity(this._size + 1);
}
this._items[this._size++] = item;
this._version++;
}
Единственная строка, которая должна быть подвержена исключению IndexOfOutRangeException, это this._items [this._size ++] = item, однако я не вижу, как я на это влияю.
Я могу решить проблему, выполнив перезагрузку домена приложения, поэтому это должно быть каким-то образом связано с кешированием. ObjectTracking отключен в DataContext, если это имеет значение.
Мне кажется, что это может быть проблема с потоками, поскольку SqlConnectionManager кэшировал IConnectionUsers в поле списка под названием «пользователи». Если два потока одновременно входят в метод Add, что предотвращает следующее:
T1: Add(x)
T2: Add(y)
T1: Since _size == _items.Length: EnsureCapacity(_size + 1)
T2: Since _size > _items.Length: _items[_size++] = item;
T1: _items[size++] = item <- OutOfRangeException since T2 didn't increase the capacity as needed
Кто-нибудь?





Вы используете общий DataContext? Это объяснило бы описываемые вами проблемы потоковой передачи, поскольку DataContext не является потокобезопасным.
Убедитесь, что все столбцы «первичного ключа» в вашем dbml действительно относятся к первичным ключам в таблицах базы данных. У меня была ситуация, когда дизайнер решил добавить дополнительный столбец PK в dbml, что означало, что LINQ to SQL не мог найти обе стороны внешнего ключа при сохранении.