我很沮丧。
我正在使用VB.Net,Linq和DataContext。我的DataContext包含一个表'transactions'。
我首先声明一个IQueryable(Of transaction)并将其分配给任何东西。我在foreach循环中构建谓词并使用transactions.Where(谓词)为IQueryable分配一个值。如果我执行IQueryable.ToList(),我会在集合中获得许多项目。
但是,在循环的下一次迭代中,IQueryable.ToList()给了我0项。
这让我发疯了。我尝试使用VSQ10的LINQ to SQL Debug Visualizer,(我用新的引用重新编译了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 。不要问我为什么。这甚至都没有得到证实,只是通过实验得出结论。一旦我弄清楚这一点,我无法弄清楚如何获得所有参数传递。所以,我放弃并在chosenCode
的每次迭代中运行查询到SQL Server。我仍然想知道如何在不运行查询的情况下完成它,直到它完全构建完毕。
我使用强类型IQueryable
来存储List(Of transaction)
的结果,而不是使用ToList()
。然后,我在其余代码中使用Linq to Objects操作该列表。
我还发现使用Union()
在生成的SQL中生成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
答案 0 :(得分:1)
我不熟悉PredicateBuilder,但我认为你正在捕捉(关闭)chosenCode
变量。
这意味着您的testRun3
已填充该运行的selectedCode,但在下一次迭代中,testRun将填充 new selectedCode。
解决方案很简单,在groupQuery = groupQuery.ToList()
之前执行Next
。
答案 1 :(得分:0)
我怀疑groupQuery.Union(vf.transactions.Where(codePredicate))
可能正在生成不返回任何记录的sql。您可能希望在Management Studio中执行相同的查询。