问题
I was speeding up my app by using compiled queries for queries which were getting hit over and over.
I tried to implement it like this:
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())
This did not work and I got this error message:
Type : System.ArgumentNullException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Value cannot be null.
Parameter name: value
However, when I changed my compiled query to return IQueryable instead of List like so:
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)
It worked fine. Can anyone shed any light as to why this is?
BTW, compiled queries rock! They sped up my app by a factor of 2.
回答1:
At a guess, this may be because the compiled query that returns an IQueryable
can be lazy-loaded, whereas the compiled query that returns a List
forces the query to be evaluated when the class is loaded (which is when Shared
members are evaluated). Quite probably, at class load time, your database connection isn't set up, so evaluation of the query fails.
Try changing the declaration of CompiledSelect
to a Shared
property, and put a breakpoint in it to see when it is actually evaluated in each case.
来源:https://stackoverflow.com/questions/2407032/why-cant-you-return-a-list-from-a-compiled-query