我很困惑。
我正在使用 VB.Net、Linq 和 DataContext。我的 DataContext 包含一个表“事务”。
我首先声明一个 IQueryable(Of transaction) 并将其分配给任何内容。我在 foreach 循环中构建谓词并使用 transactions.Where(predicate) 为 IQueryable 分配一个值。如果我执行 IQueryable.ToList(),我会在集合中获得一些项目。
但是,在循环的下一次迭代中, IQueryable.ToList() 给了我 0 个项目。
这真让我抓狂。我尝试将 LINQ to SQL Debug Visualizer 与 VS2010 一起使用,(我使用新参考重新编译了 2008 版本)但没有骰子 - 我看不到生成的 SQl 或 IQueryable 中的内容。
这是代码:
Dim groupQuery As IQueryable(Of transaction) = Nothing
For Each chosenCode As BillingCode In chosenGroup.BillingCodes
Dim testRun As List(Of transaction) = Nothing
If Not groupQuery Is Nothing Then
testRun = groupQuery.ToList()
End If
Dim codePredicate = PredicateBuilder.True(Of transaction)()
codePredicate = codePredicate.And(Function(i) i.code.Equals(chosenCode.Code))
If Not chosenCode.Description Is Nothing Then codePredicate = codePredicate.And(Function(i) i.description.ToUpper().Contains(chosenCode.Description.ToUpper()))
If Not chosenCode.Insurance Is Nothing Then codePredicate = codePredicate.And(Function(i) i.v_patient.insname.ToUpper().Contains(chosenCode.Insurance.ToUpper()))
If Not chosenCode.PriceFloor Is Nothing Then codePredicate = codePredicate.And(Function(i) i.charge >= chosenCode.PriceFloor)
If Not chosenCode.PriceCeiling Is Nothing Then codePredicate = codePredicate.And(Function(i) i.charge <= chosenCode.PriceCeiling)
Dim testRun2 As List(Of transaction) = Nothing
Dim testRun3 As List(Of transaction) = Nothing
If groupQuery Is Nothing Then
groupQuery = vf.transactions.Where(codePredicate)
Else
testRun2 = groupQuery.ToList()
groupQuery = groupQuery.Union(vf.transactions.Where(codePredicate))
testRun3 = groupQuery.ToList()
End If
Next
我会很感激任何帮助。谢谢。
编辑: “testRun”变量仅供我调试代码。我想要做的是groupQuery = groupQuery.Union(QUERY FROM THIS ITERATION)
不执行查询,直到我在代码中再转换几次。对困惑感到抱歉。
答案编辑: 我收到的两个答案都有助于最终解决方案。我最终都调用ToList()
了每次迭代,并使用Concat()
而不是Union()
. 我发现每次运行Union()
生成的 SQL 都会包含@variable
用于chosenCode
. 在我运行查询时,生成的 SQL 中可能有 10 或 20 组参数(每次迭代一组chosenCode
),但只有最后一组参数在运行时提供给 SQL Server。不要问我为什么。这甚至没有得到证实,只是通过实验得出的结论。一旦我弄清楚了这一点,我就无法弄清楚如何获取所有要传递的参数。所以,我放弃了,每次迭代都对 SQL Server 运行查询chosenCode
. 在完全构建之前,我仍然想知道如何在不运行查询的情况下执行此操作。
我没有使用 .,而是IQueryable
使用强类型List(Of transaction)
来存储ToList()
. 然后,我在其余代码中使用 Linq to Objects 操作该列表。
我还发现 using在生成的 SQL 中Union()
生成了一条UNION
语句,但这并没有给我预期的结果。因此,我使用Concat()
了 ,它在生成的 SQL 中生成了一条UNION ALL
语句,这正是我所追求的。
谢谢大家的帮助。这是代码:
For Each chosenGroup As BillingGroup In chosenGroups
Dim groupResults As List(Of transaction) = Nothing
For Each chosenCode As BillingCode In chosenGroup.BillingCodes
Dim codePredicate = PredicateBuilder.True(Of transaction)()
codePredicate = codePredicate.And(Function(i) i.code.Equals(chosenCode.Code))
If Not chosenCode.Description Is Nothing Then codePredicate = codePredicate.And(Function(i) i.description.ToUpper().Contains(chosenCode.Description.ToUpper()))
If Not chosenCode.Insurance Is Nothing Then codePredicate = codePredicate.And(Function(i) i.v_patient.insname.ToUpper().Contains(chosenCode.Insurance.ToUpper()))
If Not chosenCode.PriceFloor Is Nothing Then codePredicate = codePredicate.And(Function(i) i.charge >= chosenCode.PriceFloor)
If Not chosenCode.PriceCeiling Is Nothing Then codePredicate = codePredicate.And(Function(i) i.charge <= chosenCode.PriceCeiling)
If groupResults Is Nothing Then
groupResults = vf.transactions.Where(codePredicate).ToList()
Else
groupResults.AddRange(vf.transactions.Where(codePredicate).ToList())
End If
Next