簡體   English   中英

LINQ查詢拋出Null參考異常

[英]LINQ query throwing Null reference exception

我正在使用LINQ查詢來填充數據網格。 作為新增強功能的一部分,我必須通過在WHERE子句中包含另一個條件來更改現有的LINQ查詢。 看了這么多帖子,覺得堆疊WHERE子句條件很簡單。 早先的查詢返回簡單的對象類型(匿名)並且工作正常。 現在,我將查詢分為兩部分。 在第一部分中,我嘗試返回已知類型,並嘗試在下一部分中堆疊where子句。 但是有些方法是行不通的,沒有取得任何結果。 它在Grid上引發了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

選擇后使用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})

我希望這將有所幫助。

您收到的錯誤表明您嘗試運行的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

這將確保您不會嘗試綁定空集合,並且如果LINQ不返回任何內容,它將清除您的datagrid

但是主要問題仍然是您的LINQ正在沿行的某個地方返回一個空集合。 我主要建議返回並確保LINQ使用LINQpad或類似的其他實用工具真正恢復了您的期望。

您可以在此處獲取LinqPad。

我收到錯誤消息是因為我使用IIF進行空檢查。

有時它返回null,查詢拋出NULL引用異常。

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

  • 納雷什

我在此頁面上是因為我對此有一個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對象上的字符串屬性,並且是非空的
  • Storeys對象上的Values集合是非空的
  • 無論如何,在NullReferenceException ,應該已經通過ToList()調用對allHeights List進行了完全評估,並且解析了Values
  • 顯然,所有意外的空成員訪問都受到Elvis運算符的保護,即使所訪問的成員實際上不為空

而且,我重構了這樣的代碼:

.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。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM