Почему вы не можете вернуть список из скомпилированного запроса? - PullRequest
2 голосов
/ 09 марта 2010

Я ускорял работу своего приложения, используя скомпилированные запросы для запросов, которые снова и снова получали успех.

Я пытался реализовать это так:

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())

Это не сработало, и я получил это сообщение об ошибке:

Type : System.ArgumentNullException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Value cannot be null.
Parameter name: value

Однако, когда я изменил свой скомпилированный запрос, чтобы он возвращал IQueryable вместо List следующим образом:

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)

Работало нормально. Кто-нибудь может пролить свет на то, почему это так?

Кстати, скомпилированные запросы качаются! Они ускорили мое приложение в 2 раза.

1 Ответ

3 голосов
/ 09 марта 2010

По-видимому, это может быть потому, что скомпилированный запрос, который возвращает IQueryable, может быть загружен с отложенной загрузкой, тогда как скомпилированный запрос, который возвращает List, заставляет запрос быть оцененным при загрузке класса (который является когда Shared члены оцениваются). Вполне возможно, что во время загрузки класса ваше соединение с базой данных не установлено, поэтому оценка запроса не удалась.

Попробуйте изменить объявление CompiledSelect на Shared свойство и установите в нем точку останова, чтобы увидеть, когда она действительно оценивается в каждом случае.

...