为什么不能从编译查询中返回List?

时间:2010-03-09 06:19:43

标签: vb.net linq-to-sql compiled-query

我正在加速我的应用程序,通过使用编译查询来查询一遍又一遍的查询。

我试图像这样实现它:

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)

工作得很好。任何人都可以解释为什么会这样吗?

BTW,编译查询摇滚!他们把我的应用程序加速了2倍。

1 个答案:

答案 0 :(得分:3)

猜测,这可能是因为返回IQueryable的已编译查询可能是延迟加载的,而返回List的已编译查询会强制查询在类是已加载(在评估Shared成员时)。很可能,在类加载时,您的数据库连接未设置,因此查询的评估失败。

尝试将CompiledSelect的声明更改为Shared 属性,并在其中放置一个断点,以查看在每种情况下实际评估的时间。