我正在使用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
答案 0 :(得分: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})
我希望这会有所帮助。
答案 1 :(得分: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 Here。
答案 2 :(得分:0)
我收到错误是因为我使用IIF进行空检查。
有时它返回null并且查询抛出NULL引用异常。
现在我使用的是IF而不是IIF,它运行正常。
答案 3 :(得分: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
集合是非空的NullReferenceException
时,allHeights
列表应该已经通过ToList()
调用进行了完全评估,并且Values
已解决此外,我重构了这样的代码:
.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。