尝试过滤LINQ查询时的枚举类型异常

时间:2013-05-14 04:31:01

标签: vb.net linq entity-framework exception

我正在尝试生成一个网格,最终用户可以使用多个输入来过滤数据。

为此,我尝试按如下方式过滤初始LINQ to Entities对象:

Dim servhist As IQueryable(Of servicesHistory) = db.servicesHistories

If cboProperty.EditValue <> Nothing Then
    servhist = servhist.Where(Function(p) p.propID = CLng(cboProperty.EditValue))
End If

grdServHist.DataSource = servhist.ToList()

但是当我尝试过滤查询时,在尝试枚举集合时出现以下错误消息:“无法创建类型为'System.Object'的常量值。只有基本类型或枚举类型是在此背景下得到支持。“

我很茫然。我已经使用C#解决了这个问题,但遗憾的是无法用VB实现它。

1 个答案:

答案 0 :(得分:1)

这是Linq Expression中闭包中捕获的问题。

在英语中,这意味着您正试图将CLng(cboProperty.EditValue)传递给Linq Expression。这是合法的。但是,当Linq to Entity Framework查看它时,它无法将其转换为SQL。该表达式包含:

  1. .net类(很可能是我怀疑的winform控件)
  2. .net类
  3. 上的属性调用
  4. 对.net类的结果进行.net转换调用。
  5. 可怜的Linq2EF无法想出那些东西!然而,这将有效。

    Dim servhist As IQueryable(Of servicesHistory) = db.servicesHistories
    
    If cboProperty.EditValue <> Nothing Then
        Dim editValue = CLng(cboProperty.EditValue)
        servhist = servhist.Where(Function(p) p.propID = editValue)
    End If
    
    grdServHist.DataSource = servhist.ToList()
    

    现在看起来完全一样。但是,如果你问一个Linq Ninja,他们会告诉你两者是非常不同的,因为我已经将CLng(cboProperty.EditValue)从Linq Expression转换为函数调用。

    我个人对于Lambda表达式如何与Lambda函数具有相同的语法有两种想法,导致这些例外。

    BTW我更喜欢这种形式的查询...

    Dim editValue = CLng(cboProperty.EditValue)
    Dim servhist As IQueryable(Of servicesHistory) = _
        db.servicesHistories.Where(Function(p) p.propID = editValue or editValue is Nothing)
    grdServHist.DataSource = servhist.ToList()
    

    这允许您将IQueryable重构为已编译的查询。