0

我正在使用 LINQ 查询来填充数据网格。作为新增强功能的一部分,我必须通过在 WHERE 子句中添加一个条件来更改现有的 LINQ 查询。看了这么多帖子,感觉堆叠WHERE子句条件会很简单。早些时候,查询返回简单的对象类型(匿名)并且工作正常。现在我将查询分为两部分。在第一部分中,我试图返回已知类型并尝试在下一部分中堆叠 where 子句。但是有些这不起作用并且没有获取任何结果。它在网格上抛出 NULL 引用异常。DataBind 正在抛出异常(Null 引用异常。)在这里发布我的代码。

Using db As New ProjectDataContext
        Dim orderLines As IEnumerable(Of orderline)
        Dim customOrderLines As Object
        Try
            If VATSearch = 1 Then
                ' Show only VAT orders
                'orderlines = (From O In db.orderlines Where O.order.order_date > MinTime And O.order.order_date < MaxTime And O.order.order_status_fk > 1 And (O.ol_vat_free Is Nothing OrElse O.ol_vat_free = 0) Order By O.order.order_date _
                '        Select OrderLineID = O.ol_id, Ref = O.order.order_ref, Email = CStr(IIf(O.order.User Is Nothing, O.order.order_billing_email, O.order.User.user_email)), Code = O.StockItem.productsbycolor.product.product_code & O.StockItem.productsbycolor.color.color_code, Size = O.size.size_code, Qty = O.ol_qty, Price = O.ol_product_price, LineTotal = O.ol_lineprice, Delivery = (O.order.order_delivery_total / O.order.orderlines.Count), NonVAT = O.order.order_vat_free _
                '            )
                orderLines = (From o In db.orderlines Where o.order.order_date > MinTime And o.order.order_date < MaxTime And o.order.order_status_fk > 1 And (o.ol_vat_free Is Nothing OrElse o.ol_vat_free = 0) Order By o.order.order_date _
                Select o)


            ElseIf VATSearch = 2 Then
                ' Show only non-VAT orders
                'orderlines = (From O In db.orderlines Where O.order.order_date > MinTime And O.order.order_date < MaxTime And O.order.order_status_fk > 1 And (Not O.ol_vat_free Is Nothing) AndAlso O.ol_vat_free = 1 Order By O.order.order_date _
                '    Select OrderLineID = O.ol_id, Ref = O.order.order_ref, Email = CStr(IIf(O.order.User Is Nothing, O.order.order_billing_email, O.order.User.user_email)), Code = O.StockItem.productsbycolor.product.product_code & O.StockItem.productsbycolor.color.color_code, Size = O.size.size_code, Qty = O.ol_qty, Price = O.ol_product_price, LineTotal = O.ol_lineprice, Delivery = (O.order.order_delivery_total / O.order.orderlines.Count), NonVAT = O.order.order_vat_free _
                '                )
                orderLines = (From O In db.orderlines Where O.order.order_date > MinTime And O.order.order_date < MaxTime And O.order.order_status_fk > 1 And (Not O.ol_vat_free Is Nothing) AndAlso O.ol_vat_free = 1 Order By O.order.order_date _
                        Select O)
            Else
                ' Show both VAT and non-VAT orders
                'orderlines = (From O In db.orderlines Where O.order.order_date > MinTime And O.order.order_date < MaxTime And O.order.order_status_fk > 1 Order By O.order.order_date _
                '   Select OrderLineID = O.ol_id, Ref = O.order.order_ref, Email = CStr(IIf(O.order.User Is Nothing, O.order.order_billing_email, O.order.User.user_email)), Code = O.StockItem.productsbycolor.product.product_code & O.StockItem.productsbycolor.color.color_code, Size = O.size.size_code, Qty = O.ol_qty, Price = O.ol_product_price, LineTotal = O.ol_lineprice, Delivery = (O.order.order_delivery_total / O.order.orderlines.Count), NonVAT = O.order.order_vat_free _
                '            )
                orderLines = (From o In db.orderlines Where o.order.order_date > MinTime And o.order.order_date < MaxTime And o.order.order_status_fk > 1 Order By o.order.order_date _
                        Select o)
            End If

            customOrderLines = (From o In orderLines
                        Select orderLineID = o.ol_id, ref = o.order.order_ref, email = CStr(IIf(o.order.User Is Nothing, o.order.order_billing_email, o.order.User.user_email)),
                        code = o.StockItem.productsbycolor.product.product_code & o.StockItem.productsbycolor.color.color_code,
                        size = o.size.size_code, qty = o.ol_qty, price = o.ol_product_price, lineTotal = o.ol_lineprice,
                        delivery = (o.order.order_delivery_total / o.order.orderlines.Count), nonVAT = o.order.order_vat_free, orderPaymentType = o.order.order_google_order_number)

            results.DataSource = customOrderLines
            results.DataBind()
            results.Visible = True
            btnExportButton.Visible = True

        Catch ex As Exception

        End Try
    End Using
4

4 回答 4

0

在 select 之后使用 new 创建匿名类型并将其括在大括号中。

customOrderLines = (From o In orderLines
                    Select new { orderLineID = o.ol_id, ref = o.order.order_ref, email = CStr(IIf(o.order.User Is Nothing, o.order.order_billing_email, o.order.User.user_email)),
                    code = o.StockItem.productsbycolor.product.product_code & o.StockItem.productsbycolor.color.color_code,
                    size = o.size.size_code, qty = o.ol_qty, price = o.ol_product_price, lineTotal = o.ol_lineprice,
                    delivery = (o.order.order_delivery_total / o.order.orderlines.Count), nonVAT = o.order.order_vat_free, orderPaymentType = o.order.order_google_order_number})

我希望这将有所帮助。

于 2012-07-24T02:02:12.413 回答
0

您收到的错误表明LINQ您尝试运行的没有返回任何值,因此customOrderLines作为空集合返回。由于LINQ包括很多过滤器,我建议删除Dim customOrderLines As Object并改为执行以下操作:

Dim customOrderLines = (From o In orderLines 
  Select orderLineID = o.ol_id, ref = o.order.order_ref, 
  email = CStr(IIf(o.order.User Is Nothing, o.order.order_billing_email, o.order.User.user_email)), 
  code = o.StockItem.productsbycolor.product.product_code & o.StockItem.productsbycolor.color.color_code, 
  size = o.size.size_code, qty = o.ol_qty, price = o.ol_product_price, lineTotal = o.ol_lineprice, 
  delivery = (o.order.order_delivery_total / o.order.orderlines.Count), nonVAT = o.order.order_vat_free, 
  orderPaymentType = o.order.order_google_order_number)

if customOrderLines isnot nothing andalso customOrderLines.Any then
  results.DataSource = customOrderLines 
  results.DataBind() 
  results.Visible = True 
  btnExportButton.Visible = True
else
  results.DataSource = nothing
  results.DataBind()
  results.Visible = False
  btnExportButton.Visible = False
end if

这将确保您不会尝试绑定空集合,并且datagrid如果LINQ.

但主要问题仍然是您LINQ正在沿线某处返回一个空集合。我主要建议返回并确保LINQ使用 LINQpad 或其他类似实用程序实际带回您期望的内容。

你可以在这里得到 LinqPad 。

于 2012-07-24T16:33:14.553 回答
0

我收到错误是因为我使用 IIF 进行空值检查。

有时它返回 null 并且查询抛出 NULL 引用异常。

现在我使用 IF 而不是 IIF,它工作正常。

  • 纳雷什
于 2012-07-27T09:33:23.937 回答
0

我在这个页面上是因为我得到了NullReferenceException这个:

var allHeights = MyCities.SelectMany(city => 
    city.Houses.SelectMany(h => 
        h.Storeys.Values.Select(s => new { City = city, House = h, Storey = s })))
   .GroupBy(g => g.Storey.Height)
   .OrderBy(heightGroup => heightGroup.Key)
   .ToList();
int i = 0;
foreach (var heightGroup in allHeights)
{
    if (i > 1)
    {
        var previousHeightGroup = allHeights[i-1].ToList();
        var previousPartIDs = previousHeightGroup.Select(g => g?.City?.Name).ToList();
        //.... <do stuff in case of i > 0>
    }
    // do other stuff
    i++;
}

" previousHeightGroup.Select(g => g?.City?.Name).ToList()" 扔了一个NullReferenceException,即使:

  • 此数据结构的所有元素都不为空
  • previousHeightGroup不是空的
  • “名称”是City对象上的字符串属性并且非空
  • 对象上的Values集合Storeys非空
  • 无论如何,在调用时NullReferenceExceptionallHeights列表应该已经被ToList()调用完全评估,并且Values解决了
  • 显然,所有意外的 null 成员访问都受到 Elvis 运算符的保护,即使访问的成员实际上不是 null

此外,我重构了这样的代码:

.Select(g => {
   var group = g;
   var city = g?.City;
   var cityName = city?.Name;
   return cityName;
})

...即,我分解了 Select 内部的数据结构取消引用,并在调试器中单步执行它,一切正常。尽管如此,该Select()电话随后有一个NullReferenceException, 据称在我自己的代码中。

解决这个问题的唯一方法是稍微重构下游代码,关闭 Visual Studio (2017) 和整个机器,重新启动一切,错误不再重现。

这意味着,LINQ确实有时会在这里和那里抛出。

这是 .Net 4.6.1 。

于 2019-02-19T01:12:29.847 回答