2010-03-09 3 views
2

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

Я пытался реализовать это следующим образом:

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 вместо Список как показано на рисунке:

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) 

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

BTW, скомпилированные запросы рок! Они ускорили мое приложение с коэффициентом 2.

ответ

3

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

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