ich hab ein ganz komische Problem, bei Folgenden Code bekomme ich in der Letzten Zeile einen TimeOut.
result2 = result.Skip(51).Take(50).ToList().AsQueryable();
var result4 = result.Skip(49).Take(50).ToList().AsQueryable();
var result3 = result.Skip(50).Take(51).ToList().AsQueryable();
var result5 = result.Skip(50).Take(49).ToList().AsQueryable();
var result7 = result.Skip(40).Take(40).ToList().AsQueryable();
var result8 = result.Skip(60).Take(60).ToList().AsQueryable();
var result1 = result.Skip(50).Take(50).ToList().AsQueryable(); <- TimeOut
Die Vorangegangenen Abfragen funktionieren (99ms/31ms 2. Abfrage) und wurden hier wirklich direkt hinter einander Ausgeführt. Die Abfragen habe ich zum Teil vorher auch Einzel ausgeführt. Da kam es auch nur bei der letzten zu einem TimeOut.
Ich sehe aktuell nicht ansatzweise woran es liegen könnte. (Sehr wahrscheinlich ein dummer Fehler von mir aber ich sehe es nicht.
Zunächst ist das sehr suboptimal umgesetzt, da bei jeder Zeile die komplette Query erneut ausgeführt wird. Wenn das so gewollt ist, bitte sehr. Ansonsten würde ich mir die ersten 120 Datensätze (wenn ich mich nicht verzählt habe) in eine Liste laden und dann die einzelnen Segmente separieren.
Zu deiner Frage: Um diese zu beantworten, benötigt man imho das Tabellenlayout oder einfacher: Den SQL-Befehl, den EF in der letzten Zeile absetzt.
Das ist natürlich nicht die produktive Implementierung. Im Eindefekt wird ein IQueryabel (deshalb auch der Cast) zurück gegeben um in der UI Pageing umzusetzen. Wo es dann zu TimeOuts kommt.
Bei der Untersuchung konnte ich Feststellen, das mit Skip(50).Take(50) sich der TimeOut reproduzieren lässt. Der nächste schritt war dann, das von Linq erzeugte SQL direkt auf dem Server auszuführen (wenn es da schon lange dauert, wird es in Programm auch nicht funktionieren). Das Funktionierte aber problemlos. Nach dem ich ein paar Sachen Probiert hatte, bin ich hingegange und hab Skip auf 49 gesetzt, um die Query auf den SQL Server besser erkennen zu können. Die lief aber problem los durch. Die Nächte Vermutung war, dass es vielleicht am letzten Datensatz liegt, der Fehlt ja bei Skip(49). Also hab ich Skip auf 51 gesetzt, damit der Datensatz mit dabei ist, was aber auch problemlos funktionierte. Das das Problem auftritt wenn der 1 und letzte Datensatz Enthalten sind hab ich mit Skip(50).Take(51) geprüft, lief auch problemlos.
Aktuell fehlt mir ein Ansatz woran es liegen könnte. Meine Arbeitskollegen hab ich auch schon gefragt, die haben aber auch keinen Ansatz.
Das es ein Grundlegendes Problem bei Skip/Take gibt schließe ich eigentlich aus. Dafür ist Linq zu oft im Einsatz.
Am Wahrscheinlichsten, ist das ich etwas Dummes mache. Ich sehe es aber einfach nicht. Mit meinem Blickwinkel auf Problem, stehe ich mir da wohl selber gerade im Weg. Und da hoffe ich einfach auf das Forum. Ich bin für jede Idee dankbar.
Linq2SQL übersetzt doch auch nur LINQ in SQL, d.h. wie sieht der konkrete Befehl denn aus? Deiner Antwort entnehme ich nicht, dass Du den konkreten Befehl im SSMS ausgeführt hast.
Ich tippe (blind) auf einen Fehler im SQL-Server. Also kein Bug, sondern irgend etwas mit der Query.
Der nächste schritt war dann, das von Linq erzeugte SQL direkt auf dem Server auszuführen (wenn es da schon lange dauert, wird es in Programm auch nicht funktionieren)
Zitat von alzaimar
Linq2SQL übersetzt doch auch nur LINQ in SQL, d.h. wie sieht der konkrete Befehl denn aus? Deiner Antwort entnehme ich nicht, dass Du den konkreten Befehl im SSMS ausgeführt hast.
Ja hab ich gemacht.
Danke trozdem für die Antwort. Ich bin für jeder hilfe dankbar.
Hupsa, übersehen... Aber der Timeout kommt von... wem? Das müsste sich aus der Exception ergeben. Da meckert doch ADO.NET, oder? Mit dem Profiler müsste man zudem genau erkennen können, was der Server so alles macht.
Nächster Versuch: Erzeuge eine Testtabelle und verwende dein Konstrukt dafür.
Klappt das? Wenn ja: Wo sind die Unterschiede?
Was ist 'result'? Ist das bereits ein Linq-Konstrukt? Müsste es eigentlich.
EDIT: Hier stand Murks: Erst testen, dann posten...
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von alzaimar am .
Bei der Exception sehe ich jetzt nicht ungewöhliches, ist für mich einfach ein TimeOut
Fehler
System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Timeout abgelaufen. Das Zeitlimit wurde vor dem Beenden des Vorgangs überschritten oder der Server reagiert nicht. ---> System.ComponentModel.Win32Exception: Der Wartevorgang wurde abgebrochen
--- Ende der internen Ausnahmestapelüberwachung ---
bei System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
bei System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
bei System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
bei System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
bei System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
bei System.Data.SqlClient.SqlDataReader.get_MetaData()
bei System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
bei System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
bei System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
bei System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
bei System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
bei System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
bei System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
bei System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)
bei System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
bei System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
bei System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
bei System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
bei System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
--- Ende der internen Ausnahmestapelüberwachung ---
bei System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
bei System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
bei System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass3.<GetResults>b__2()
bei System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
bei System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass3.<GetResults>b__1()
bei System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
bei System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
bei System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
bei System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
bei System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
bei System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
Ja result ist ist ein Linq Konstrukt, mit joins über mehrere Tabellen mit einer where und order by Klauseln.
Grundlegend funktioniert die Abfrage auch auf die Tabellen. Ich darf hald bei Skip/Take nur den Wert 50 nicht verwenden.
Die läuft auf ein TimeOut, dabei ist da eigendlich nur 1 Datensatz weniger drin als in Abfrage(1). (Ich hab da jetzt wirklich nur die Zahlen geändert).
Kannst du einmal die beiden SQL-Abfragen posten, die das EF dir generiert?
Irgendwo muss ein Unterschied sein... Oder die Ergebnismenge für Abfrage 2 ist wesentlich größer als bei Abfrage 1 und irgendein Index greift hier nicht...
SELECT TOP (51)
[Project1].[tblPcb_ID] AS [tblPcb_ID],
[Project1].[Barcode] AS [Barcode],
[Project1].[ProgrammName] AS [ProgrammName],
[Project1].[Charge] AS [Charge],
[Project1].[DateTime] AS [DateTime],
[Project1].[tblTraceState_ID] AS [tblTraceState_ID],
[Project1].[IdentNr] AS [IdentNr],
[Project1].[KurzName] AS [KurzName],
[Project1].[LinienNr] AS [LinienNr],
[Project1].[MaschinenNr] AS [MaschinenNr],
[Project1].[tblPcb_Name] AS [tblPcb_Name]
FROM ( SELECT [Project1].[tblPcb_ID] AS [tblPcb_ID], [Project1].[tblPcb_Name] AS [tblPcb_Name], [Project1].[tblTraceState_ID] AS [tblTraceState_ID], [Project1].[DateTime] AS [DateTime], [Project1].[MaschinenNr] AS [MaschinenNr], [Project1].[LinienNr] AS [LinienNr], [Project1].[Barcode] AS [Barcode], [Project1].[Charge] AS [Charge], [Project1].[IdentNr] AS [IdentNr], [Project1].[KurzName] AS [KurzName], [Project1].[ProgrammName] AS [ProgrammName], row_number() OVER (ORDER BY [Project1].[tblTraceState_ID] DESC) AS [row_number]
FROM ( SELECT
[Extent1].[tblPcb_ID] AS [tblPcb_ID],
[Extent1].[tblPcb_Name] AS [tblPcb_Name],
[Extent2].[tblTraceState_ID] AS [tblTraceState_ID],
[Extent2].[DateTime] AS [DateTime],
[Extent2].[MaschinenNr] AS [MaschinenNr],
[Extent2].[LinienNr] AS [LinienNr],
[Extent3].[Barcode] AS [Barcode],
[Extent3].[Charge] AS [Charge],
[Extent4].[IdentNr] AS [IdentNr],
[Extent5].[KurzName] AS [KurzName],
[Extent6].[ProgrammName] AS [ProgrammName]
FROM [dbo].[BESTPcb] AS [Extent1]
INNER JOIN [dbo].[TraceState] AS [Extent2] ON [Extent1].[tblPcb_ID] = [Extent2].[tblPcb_ID]
INNER JOIN [dbo].[LAGERStore] AS [Extent3] ON [Extent2].[tblStore_ID] = [Extent3].[tblStore_ID]
INNER JOIN [dbo].[BLIBComponent] AS [Extent4] ON [Extent3].[tblComponent_ID] = [Extent4].[tblComponent_ID]
LEFT OUTER JOIN [dbo].[BESTPosition] AS [Extent5] ON [Extent2].[tblPosition_ID] = [Extent5].[tblPosition_ID]
INNER JOIN [dbo].[BESTReference] AS [Extent6] ON [Extent1].[tblReference_ID] = [Extent6].[tblReference_ID]
WHERE ([Extent1].[tblPcb_Name] = @p__linq__0) OR (([Extent1].[tblPcb_Name] IS NULL) AND (@p__linq__0 IS NULL))
) AS [Project1]
) AS [Project1]
WHERE [Project1].[row_number] > 49
ORDER BY [Project1].[tblTraceState_ID] DESC
p__linq__0: '1/1' (Type = String, Size = 4000)
Executing at 27.07.2015 14:00:23 +02:00
Completed in 79 ms with result: SqlDataReader
Das nicht funktionierende so:
SELECT TOP (50)
[Project1].[tblPcb_ID] AS [tblPcb_ID],
[Project1].[Barcode] AS [Barcode],
[Project1].[ProgrammName] AS [ProgrammName],
[Project1].[Charge] AS [Charge],
[Project1].[DateTime] AS [DateTime],
[Project1].[tblTraceState_ID] AS [tblTraceState_ID],
[Project1].[IdentNr] AS [IdentNr],
[Project1].[KurzName] AS [KurzName],
[Project1].[LinienNr] AS [LinienNr],
[Project1].[MaschinenNr] AS [MaschinenNr],
[Project1].[tblPcb_Name] AS [tblPcb_Name]
FROM ( SELECT [Project1].[tblPcb_ID] AS [tblPcb_ID], [Project1].[tblPcb_Name] AS [tblPcb_Name], [Project1].[tblTraceState_ID] AS [tblTraceState_ID], [Project1].[DateTime] AS [DateTime], [Project1].[MaschinenNr] AS [MaschinenNr], [Project1].[LinienNr] AS [LinienNr], [Project1].[Barcode] AS [Barcode], [Project1].[Charge] AS [Charge], [Project1].[IdentNr] AS [IdentNr], [Project1].[KurzName] AS [KurzName], [Project1].[ProgrammName] AS [ProgrammName], row_number() OVER (ORDER BY [Project1].[tblTraceState_ID] DESC) AS [row_number]
FROM ( SELECT
[Extent1].[tblPcb_ID] AS [tblPcb_ID],
[Extent1].[tblPcb_Name] AS [tblPcb_Name],
[Extent2].[tblTraceState_ID] AS [tblTraceState_ID],
[Extent2].[DateTime] AS [DateTime],
[Extent2].[MaschinenNr] AS [MaschinenNr],
[Extent2].[LinienNr] AS [LinienNr],
[Extent3].[Barcode] AS [Barcode],
[Extent3].[Charge] AS [Charge],
[Extent4].[IdentNr] AS [IdentNr],
[Extent5].[KurzName] AS [KurzName],
[Extent6].[ProgrammName] AS [ProgrammName]
FROM [dbo].[BESTPcb] AS [Extent1]
INNER JOIN [dbo].[TraceState] AS [Extent2] ON [Extent1].[tblPcb_ID] = [Extent2].[tblPcb_ID]
INNER JOIN [dbo].[LAGERStore] AS [Extent3] ON [Extent2].[tblStore_ID] = [Extent3].[tblStore_ID]
INNER JOIN [dbo].[BLIBComponent] AS [Extent4] ON [Extent3].[tblComponent_ID] = [Extent4].[tblComponent_ID]
LEFT OUTER JOIN [dbo].[BESTPosition] AS [Extent5] ON [Extent2].[tblPosition_ID] = [Extent5].[tblPosition_ID]
INNER JOIN [dbo].[BESTReference] AS [Extent6] ON [Extent1].[tblReference_ID] = [Extent6].[tblReference_ID]
WHERE ([Extent1].[tblPcb_Name] = @p__linq__0) OR (([Extent1].[tblPcb_Name] IS NULL) AND (@p__linq__0 IS NULL))
) AS [Project1]
) AS [Project1]
WHERE [Project1].[row_number] > 50
ORDER BY [Project1].[tblTraceState_ID] DESC
p__linq__0: '1/1' (Type = String, Size = 4000)
-- Executing at 27.07.2015 14:02:03 +02:00
-- Failed in 30193 ms with error: Timeout abgelaufen. Das Zeitlimit wurde vor dem Beenden des Vorgangs überschritten oder der Server reagiert nicht.
Closed connection at 27.07.2015 14:02:33 +02:00
Kann das sein, dass das zusätzliche Element, das Du hier lädst, irgendwie fehlerhaft ist und dadurch das Timeout ausgelöst wird?
Der Query ist nämlich soweit identisch.
Die DB ist grob 11GB groß (20Millionendatensätze), wobei ca. 90% der Daten in der TraceState Tabelle sind. Welche in der Abfrage mit drin ist ohne Skip/Take liefert die Abfrage grob 20.000 Datensätze zurück.
Ich denke nicht, das ich da Ansatzweise realistisch die Daten bereitstellen kann.
Da an anderen stellen im Programm auch Skip/Take verwendet wird und problemlos funktioniert, befürchte ich das sich der Fehler nicht Reproduzieren lässt, wenn ich probiere da eine Abgespeckte Variante erzeuge. (Ich kann dir aber Anbieten per TeamViewer auf meinen Rechner zu schauen)
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Palin am .
ich war mal so frei die Frage auch im MSDN Forum zu stellen. Weil ich da aktuell echt auch dem Schlauch stehen. Falls ich dort eine Hilfreiche Antwort bekomme. Poste ich sie natürlich hier.
wie hast du denn das SQL der Statements extrahiert? Per SQL-Profiler? Falls nicht würde ich das nochmal probieren: Die komplette Abfrage (nicht nur die einzelnen separiert) im Profiler loggen lassen und dann gemeinsam im SSMS ausführen lassen um zu sehen obs dort funktioniert.
Weiters kann es sein (und hatte ich schonmal), dass Sachen im SSMS funktionieren, die aber im PGM nicht funktionierten. Ich kann mich nur mehr grob daran erinnern, dass "SET ARITHABORT OFF/ON" da teilweise geholfen hat bzw. kann es auch Probleme mit dem Ausführungsplänen im SQL Server geben. Evt. mal die irgendwo resetten probieren.
Wie schauts aus, wenn du das Timeout anhebst? Wird die anfrage dann fertig oder nicht?
@xxxprod ich hate das TimeOut schon mal höher gestellt (180), damit war es nicht durchgelaufen. Ich hatte dann jetzt auf deine Anfrage das TimeOut mal auf 1000 gesetzt, damit ist die Abfrage dann durchgelaufen.
Meine aktuelle Vermutung ist, das der Server für die Funktionierende Abfrage, auf eine Vorher schon ausgeführte Abfrage zurück gegriffen hat. Wehrend er bei der anderen die Abfrage neu erstellt hat was zu einem TimeOut führte.
Nun ja erst mal funktionierst und ich hab einen Ansatz voran es liegen könnte.