2008-10-16 5 views
7

J'ai un site ASP.NET qui fonctionne parfaitement depuis longtemps, rien n'a changé récemment. D'une heure à l'autre, je commencé à recevoir une IndexOutOfRangeException en ligne où je fais une requête LINQ comme ceci:IndexOutOfRangeException sur Queryable.Single

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

ORMB.Form est un objet POCO avec LINQ to SQL attributs mapping à une table de MSSQL (cartographie est vérifié comme correct). Le stacktrace est la suivante:

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) 

Reflétant System.Collections.Generic.List.Add montre le code suivant:

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

La seule ligne qui devrait être sujette à l'IndexOfOutRangeException est this._items [ this._size ++] = item, je ne vois pas comment j'affecte cela cependant.

Je peux résoudre le problème en faisant un recyclage appdomain, de sorte qu'il doit être lié à la mise en cache en quelque sorte. ObjectTracking est désactivé sur le DataContext, dans le cas où cela est important. Mon intuition est que cela pourrait être un problème de threading, SqlConnectionManager ayant mis IConnectionUsers en cache dans le champ List appelé 'users'. Si deux threads entrent dans la méthode Add en même temps, ce qui empêche le suivant de se produire:

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 

N'importe qui?

Répondre

3

Partagez-vous un DataContext commun? Cela expliquerait les problèmes de threads que vous décrivez, car DataContext n'est pas thread-safe.

0

Vérifiez que toutes les colonnes "clé primaire" de votre dbml correspondent aux clés primaires des tables de base de données. J'ai juste eu une situation où le concepteur a décidé de mettre une colonne PK supplémentaire dans le dbml, ce qui signifie que LINQ to SQL n'a pas pu trouver les deux côtés d'une clé étrangère lors de l'enregistrement.

Questions connexes