2008-10-10 25 views
10

Ich habe eine Tabelle, werden wir Users nennen. Diese Tabelle hat einen einzelnen Primärschlüssel, der in SQL Server definiert ist - ein Autoinkrement int ID.Seltsam LINQ Exception (Index außerhalb der Grenzen)

Manchmal scheitern meine LINQ-Abfragen für diese Tabelle mit einem "Index was outside the range" Fehler - selbst die einfachsten Abfragen. Die Abfrage selbst verwendet keine Indexer.

Zum Beispiel:

User = Users.Take(1); 

oder

IEnumerable<Users> = Users.ToList(); 

Beide Abfragen warf den gleichen Fehler. Mit dem Debugger Visualizer, um die generierte Abfrage zu sehen - ich kopiere und füge die Abfrage in SQL und es funktioniert gut. Ich klicke auch auf "Ausführen" auf dem Visualizer und es funktioniert gut. Die Ausführung des Codes führt jedoch zu diesem Fehler. Ich implementiere keine der partiellen Methoden in der Klasse, also passiert dort nichts. Wenn ich meinen Debugger neu starte, verschwindet das Problem, nur um den Kopf ein paar Stunden später wieder nach oben zu ziehen. Kritisch, ich sehe diesen Fehler in meinen Fehlerprotokollen von der App, die in der Produktion läuft.

Ich mache eine Menge LINQ in meiner App, gegen ein Dutzend verschiedener Entitäten in meiner Datenbank, aber ich sehe dieses Problem nur bei Abfragen, die sich auf eine bestimmte Entität in meiner Tabelle beziehen. Einige Googeln haben vorgeschlagen, dass dieses Problem auf eine falsche Beziehung zwischen meinem Modell und einem anderen Unternehmen angegeben in Zusammenhang stehen könnte, aber ich habe nicht keine Beziehungen mit diesem Objekt. Es scheint 95% der Zeit zu funktionieren, nur die anderen 5% scheitern.

Ich habe gelöscht vollständig das Objekt aus dem Designer, und es von einem „aufgefrischt“ Server-Browser erneut hinzugefügt, und dass das Problem nicht beheben.

Irgendwelche Ideen, was hier vor sich geht?

Hier ist die vollständige Fehlermeldung und Stack-Trace:

Index außerhalb des zulässigen Bereichs war. Muss nicht negativ sein und weniger als die Größe der Sammlung. Parametername: Index bei System.Data.Linq.SqlClient.SqlProvider.Execute (Expression Abfrage, Queryquery, IObjectReaderFactory Fabrik, Object [] parentArgs, Object [] userArgs, ICompiledSubQuery [] Subqueries, Object lastresult) bei System.Data.Linq.SqlClient.SqlProvider.ExecuteAll (Expression Abfrage, Query [] queryInfos, IObjectReaderFactory Fabrik, Object [] userArguments, ICompiledSubQuery [] Subqueries) bei System.Data.Linq.SqlClient.SqlProvider.System.Data .Linq.Provider.IProvider.Execute (Ausdruck Abfrage) um System.Data.Linq.Table 1.System.Linq.IQueryProvider.Execute[TResult](Expression expression) at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable 1 Quelle, Ausdruck `1 Prädikat) bei MyProject.FindUserByType (String typeId)

BEARBEITEN: Wie unten beschrieben, ist eine Kopie des Tabellenschemas.

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: Der Stack-Trace zeigt FirstOrDefault, aber ich dupliziert den Fehler sowohl Take() und ToList() verwenden. Der Stack-Trace ist zwischen all diesen identisch, einfach interchangnig FirstOrDefault/Take/ToList. Die Abwärtsbewegung des Stapels zu SqlProvider.Execute ist tatsächlich identisch.

+0

Keine Ahnung was passiert, aber faszinierend! Wenn alles andere fehlschlägt, können Sie die General Linq Project Liste versuchen: http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=123&SiteID=1 –

+0

Es könnte hilfreich sein, wenn wir die Tabellendefinition sehen könnten. – KyleLanser

+0

(mssql -> Datenbanken -> the_db -> Tabellen -> the_bad_table -> Rechtsklick -> Skripttabelle als -> Create To) – KyleLanser

Antwort

0

Die Ausnahme tritt in einer Systembibliothek auf und Ihre Geschichte lässt mich glauben, dass das Problem nicht in Ihrem Code enthalten ist. Hat sich das Schema kürzlich geändert? Ist Ihr Mapping korrekt?

+0

Das Schema hat sich in letzter Zeit nicht geändert, obwohl ich seit einiger Zeit Probleme hatte. Ich entfernte die Täter-Tabelle und fügte sie über den Server-Browser wieder hinzu, ohne Erfolg. – Matt

1

Ich würde sagen, dass Sie irgendwo ein Modell -> Datenbank-Mismatch haben. Wenn ich in solchen Situationen so verzweifelt wie Sie bin, starte ich normalerweise VS.NET, erstelle eine neue Konsolenanwendung und baue den Abschnitt der DBML neu, der auf die Entität verweist, die in dieser Abfrage von Interesse ist, und führe sie erneut aus. Sie können feststellen, dass die Abfrage in dieser Art von Isolation funktioniert. Haben Sie Ihre Entitätsdefinitionen angepasst, indem Sie Teilmethoden ausgefüllt haben, insbesondere diejenigen, die auf die Erstellung feuern?

-1

Schuss im Dunkeln:

Sie rufen MyProject.FindUserByType (String TypeId) innerhalb eines Schleifenkörpers, unter Verwendung der Schleifenvariablen als Parameter.

Verwenden Sie die Schleifenvariable nicht direkt.

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

Wenn dies erweist sich der Fall zu sein, werde ich diese Antwort aktualisieren, um zu erklären, warum Variablen Schleife direkt eine schlechte Praxis ist (nachdem Sie die Frage aktualisieren, um die Schleife zu zeigen).

+0

Hier ist, wo ich Index außerhalb des Bereichs und LINQ to SQL vor http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3782912&SiteID=1 –

+0

Hallo David gesehen habe. Ich mache eigentlich keine Loopings. Ich nehme an, Sie meinen, dass die verzögerte Ausführung der Abfrage dazu führen könnte, dass ein anderer Wert verwendet wird als ursprünglich beabsichtigt, da er sich während des Schleifens geändert hat. Es ist jedoch ein interessanter Punkt, da es mir nicht aufgefallen ist. – Matt

5

Dies wird mit ziemlicher Sicherheit nicht jedermanns Ursache sein, aber ich traf genau diese Ausnahme in meinem Projekt - und stellte fest, dass die Ursache darin lag, dass während der Erstellung einer Entitätsklasse eine Ausnahme ausgelöst wurde. Seltsamerweise ist die wahre Ausnahme "verloren" und manifestiert sich stattdessen als eine ArgumentOutOfRange-Ausnahme, die vom Iterator der Linq-Anweisung stammt, die das Objekt/s abruft.

Wenn Sie diesen Fehler erhalten und OnCreated- oder OnLoaded-Methoden in Ihren POCOs eingeführt haben, versuchen Sie, diese Methoden zu durchlaufen.

+0

In der Tat ist es eine andere Art von Ausnahme durch diese "außerhalb der Reichweite" versteckt. In meinem Fall hatte ich das gleiche Problem und es war, dass das Objekt, das ich ändern wollte, in einem ungültigen Kontext war. – Hannish

0

Dieses Problem tritt auf, weil das linq-Objekt und die Datenbankfelder dieser Tabelle nicht identisch sind.

0

Ich hatte dieses Problem auch und löste es.

Jetzt verstehe ich den Fehler war falsche Verwendung von Linq Data Context, aber vielleicht kann meine Erfahrung immer noch anderen helfen, zu verstehen, warum sie diesen Fehler erhalten.

Linq Datenkontext ist nicht für die gleichzeitige Ausführung vorgesehen. Daher ist das Erstellen mehrerer Tasks, die async ausführen, nicht ideal. Überprüfen Sie folgenden Beispielcode zu verstehen, die Frage:

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

In meinem Szenario, ich vorging den Datenkontext als Parameter in einem längeren Call-Stack und rufe asynchrone Methoden auf dem Weg. So war es nicht so offensichtlich wie oben Beispiel. Aber vielleicht kann das jemand anderem helfen :-)

Verwandte Themen