为什么不能从编译的查询中返回列表?

发布于 2024-08-24 13:49:06 字数 1404 浏览 3 评论 0原文

我通过使用编译查询来加速我的应用程序,这些查询一次又一次地受到攻击。

我尝试像这样实现它:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凯凯我们等你回来 2024-08-31 13:49:06

据猜测,这可能是因为返回 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 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文