2 Stimmen

Warum kann man keine Liste aus einer kompilierten Abfrage zurückgeben?

Ich habe meine App beschleunigt, indem ich kompilierte Abfragen für Abfragen verwendet habe, die immer wieder ausgeführt wurden.

Ich habe versucht, es so zu implementieren:

Function Select(ByVal fk_id As Integer) As List(SomeEntity)
    Using db As New DataContext()
        db.ObjectTrackingEnabled = False
        Return CompiledSelect(db, fk_id)
    End Using
End Function

Shared CompiledSelect As Func(Of DataContext, Integer, List(Of SomeEntity)) = _
    CompiledQuery.Compile(Function(db As DataContext, fk_id As Integer) _
         (From u In db.SomeEntities _
          Where u.SomeLinkedEntity.ID = fk_id _
          Select u).ToList())

Dies hat nicht funktioniert und ich habe diese Fehlermeldung erhalten:

Typ: System.ArgumentNullException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Nachricht: Der Wert darf nicht NULL sein.
Parametername: Wert

Aber als ich meine kompilierte Abfrage geändert habe, um IQueryable statt List zurückzugeben, wie folgt:

Function Select(ByVal fk_id As Integer) As List(SomeEntity)
    Using db As New DataContext()
        db.ObjectTrackingEnabled = False
        Return CompiledSelect(db, fk_id).ToList()
    End Using
End Function

Shared CompiledSelect As Func(Of DataContext, Integer, IQueryable(Of SomeEntity)) = _
    CompiledQuery.Compile(Function(db As DataContext, fk_id As Integer) _
         From u In db.SomeEntities _
         Where u.SomeLinkedEntity.ID = fk_id _
         Select u)

hat es gut funktioniert. Kann jemand erklären, warum das so ist?

Übrigens, kompilierte Abfragen sind großartig! Sie haben meine App um den Faktor 2 beschleunigt.

4voto

AakashM Punkte 60642

Meiner Vermutung nach liegt dies daran, dass die kompilierte Abfrage, die ein IQueryable zurückgibt, lazy-loaded sein kann, während die kompilierte Abfrage, die eine List zurückgibt, dazu zwingt, dass die Abfrage ausgewertet wird, wenn die Klasse geladen wird (was passiert, wenn Shared-Elemente ausgewertet werden). Wahrscheinlich ist zur Ladezeit der Klasse die Datenbankverbindung nicht aufgebaut, sodass die Auswertung der Abfrage fehlschlägt.

Versuchen Sie, die Deklaration von CompiledSelect auf eine Shared Eigenschaft zu ändern und setzen Sie einen Haltepunkt darin, um zu sehen, wann es tatsächlich in jedem Fall ausgewertet wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X