简体   繁体   English

LINQ查询抛出Null参考异常

[英]LINQ query throwing Null reference exception

I am using LINQ query to populate a datagrid. 我正在使用LINQ查询来填充数据网格。 As part of the new enhancement I have to change the existing LINQ query by including one more condition in WHERE clause. 作为新增强功能的一部分,我必须通过在WHERE子句中包含另一个条件来更改现有的LINQ查询。 Looked at so many posts and felt stacking WHERE clause condition would be simple. 看了这么多帖子,觉得堆叠WHERE子句条件很简单。 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. 在第一部分中,我尝试返回已知类型,并尝试在下一部分中堆叠where子句。 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. 它在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

use new after select to create anonymous type and enclose it in braces. 选择后使用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})

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. 您收到的错误表明您尝试运行的LINQ没有返回任何值,因此customOrderLines作为空集合返回。 Since the LINQ includes quite a few filters I would suggest removing Dim customOrderLines As Object and instead doing something like: 由于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

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 . 这将确保您不会尝试绑定空集合,并且如果LINQ不返回任何内容,它将清除您的datagrid

But the main issue is still that your LINQ is returning an empty collection somewhere along the line. 但是主要问题仍然是您的LINQ正在沿行的某个地方返回一个空集合。 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. 我主要建议返回并确保LINQ使用LINQpad或类似的其他实用工具真正恢复了您的期望。

You can get LinqPad Here . 您可以在此处获取LinqPad。

I was getting error because I was using IIF for null check. 我收到错误消息是因为我使用IIF进行空检查。

Sometimes it is returning null and query was throwing NULL reference exception. 有时它返回null,查询抛出NULL引用异常。

Now I am using IF instead of IIF and it is working fine. 现在,我使用的是IF而不是IIF,它工作正常。

  • Naresh 纳雷什

I am on this page because I got a NullReferenceException on this: 我在此页面上是因为我对此有一个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() " threw a NullReferenceException , even though: previousHeightGroup.Select(g => g?.City?.Name).ToList() ”引发了NullReferenceException ,即使:

  • None of the elements of this data structure was null 该数据结构的所有元素都不为空
  • The previousHeightGroup was not empty previousHeightGroup不为空
  • The "Name" was a string property on the City object and was nonempty “名称”是City对象上的字符串属性,并且是非空的
  • The Values collection on the Storeys object is nonempty Storeys对象上的Values集合是非空的
  • Anyway, at the time of the NullReferenceException , the allHeights List should have been fully evaluated by the ToList() call, and the Values resolved 无论如何,在NullReferenceException ,应该已经通过ToList()调用对allHeights List进行了完全评估,并且解析了Values
  • obviously, all accidental null member accesses are protected with the Elvis operator, even though the members accessed are actually not null 显然,所有意外的空成员访问都受到Elvis运算符的保护,即使所访问的成员实际上不为空

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. ...即,我分解了Select中引用的数据结构,并在调试器中单步调试它,一切正常。 Nevertheless, the Select() call then had a NullReferenceException , allegedly in my own code. 尽管如此, Select()调用仍然具有NullReferenceException ,据称在我自己的代码中。

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. 解决此问题的唯一方法是稍微向下重构代码,关闭Visual Studio(2017)和整个计算机,重新启动所有内容,并且该错误不再重现。

That means, LINQ does throw up sometimes here and there. 这意味着,LINQ有时确实会到处乱扔。

This was .Net 4.6.1 . 这是.Net 4.6.1。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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