2008-10-16 4 views
7

Mam witrynę ASP.NET, która działa doskonale od dawna, nic się ostatnio nie zmieniło. Od jednej godziny do następnego zacząłem otrzymania IndexOutOfRangeException w linii gdzie robię kwerendy LINQ tak:IndexOutOfRangeException on Queryable.Single

var form = SqlDB.GetTable<ORMB.Form, CDB>() 
    .Where(f => f.FormID == formID) 
    .Single(); 

ORMB.Form jest obiektem POCO z LINQ to SQL atrybuty przyporządkowując je do tabeli MSSQL (mapowanie jest zweryfikowany jako poprawny). StackTrace jest następujący:

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) 

, odzwierciedlające System.Collections.Generic.List.Add przedstawia poniższy kod:

public void Add(T item) 
{ 
    if (this._size == this._items.Length) 
    { 
     this.EnsureCapacity(this._size + 1); 
    } 
    this._items[this._size++] = item; 
    this._version++; 
} 

Jedynym linii, które powinny być podatne na IndexOfOutRangeException jest this._items [ this._size ++] = item, nie widzę, jak mam na to wpływ.

Mogę rozwiązać problem, wykonując recykling w domenie aplikacji, więc musi być w jakiś sposób buforowany. ObjectTracking jest wyłączony w DataContext, jeśli ma to znaczenie.

Mam przeczucie, że może to być problem z wątkami, SqlConnectionManager z buforowanymi użytkownikami IConnection w polu Lista o nazwie "użytkownicy". Jeśli dwa wątki jednocześnie wprowadzają metodę Add, co uniemożliwia następujące zdarzenia:

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 

Ktoś?

Odpowiedz

3

Czy udostępniasz wspólny obiekt DataContext? To by wyjaśniało problemy z gwintowaniem, które opisujesz, ponieważ DataContext nie jest bezpieczny dla wątków.

0

Sprawdź, czy wszystkie kolumny "klucza podstawowego" w Twoim dbml rzeczywiście odnoszą się do kluczy podstawowych w tabelach bazy danych. Właśnie zdarzyło się, że projektant postanowił umieścić dodatkową kolumnę PK w dbml, co oznaczało, że LINQ do SQL nie mógł znaleźć obu stron obcego klucza podczas zapisywania.