为什么不能从编译的查询中返回列表?
我通过使用编译查询来加速我的应用程序,这些查询一次又一次地受到攻击。
我尝试像这样实现它:
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 倍。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
据猜测,这可能是因为返回
IQueryable
的编译查询可以延迟加载,而返回List
的编译查询会强制在以下情况下评估查询:类被加载(这是在评估 Shared 成员时)。很可能,在类加载时,您的数据库连接尚未设置,因此查询的评估失败。尝试将
CompiledSelect
的声明更改为Shared
属性,并在其中放置一个断点以查看每种情况下何时实际评估它。At a guess, this may be because the compiled query that returns an
IQueryable
can be lazy-loaded, whereas the compiled query that returns aList
forces the query to be evaluated when the class is loaded (which is whenShared
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 aShared
property, and put a breakpoint in it to see when it is actually evaluated in each case.