简体   繁体   中英

LINQ query throwing Null reference exception

I am using LINQ query to populate a datagrid. As part of the new enhancement I have to change the existing LINQ query by including one more condition in WHERE clause. Looked at so many posts and felt stacking WHERE clause condition would be simple. Earlier the query was returning simple object type(anonymous) and working fine. Now I divided the query into 2 parts. In first part I am trying to return the known type and trying to stack where clause in the next part. But some how this is not working and not fetching any results. It is throwing NULL reference exception on grid.DataBind is throwing exception(Null reference exception.) Posting my code here.

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

use new after select to create anonymous type and enclose it in braces.

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})

I hope this will help.

The error you are getting indicates that the LINQ you are trying to run isn't returning any values so customOrderLines is coming back as an empty collection. Since the LINQ includes quite a few filters I would suggest removing Dim customOrderLines As Object and instead doing something like:

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

This will ensure that you don't try to bind an empty collection and also it will clear out your datagrid if nothing is returned by the LINQ .

But the main issue is still that your LINQ is returning an empty collection somewhere along the line. I would mainly suggest going back and ensuring that the LINQ is actually bringing back what you expect using LINQpad or another utility like it.

You can get LinqPad Here .

I was getting error because I was using IIF for null check.

Sometimes it is returning null and query was throwing NULL reference exception.

Now I am using IF instead of IIF and it is working fine.

  • Naresh

I am on this page because I got a NullReferenceException on this:

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() " threw a NullReferenceException , even though:

  • None of the elements of this data structure was null
  • The previousHeightGroup was not empty
  • The "Name" was a string property on the City object and was nonempty
  • The Values collection on the Storeys object is nonempty
  • Anyway, at the time of the NullReferenceException , the allHeights List should have been fully evaluated by the ToList() call, and the Values resolved
  • obviously, all accidental null member accesses are protected with the Elvis operator, even though the members accessed are actually not null

Moreover, I refactored the code like this:

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

... ie, I broke up the data structure dereferencing inside the Select and single-stepped through it in the debugger, it all worked fine. Nevertheless, the Select() call then had a NullReferenceException , allegedly in my own code.

The only way to fix this was to refactor the code downstream a little, shut down Visual Studio (2017) and the entire machine, restart everything, and the error did not reproduce any more.

That means, LINQ does throw up sometimes here and there.

This was .Net 4.6.1 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM