Vb.net 意外的IQueryable<&燃气轮机;ForEach迭代后的值

Vb.net 意外的IQueryable<&燃气轮机;ForEach迭代后的值,vb.net,linq-to-sql,union,Vb.net,Linq To Sql,Union,我很困惑 我正在使用VB.Net、Linq和DataContext。My DataContext包含一个表“transactions” 我首先声明一个IQueryable(事务的),并将其赋值为nothing。我在foreach循环中构建了一个谓词,并使用transactions.Where(谓词)为IQueryable赋值。如果执行IQueryable.ToList(),则会在集合中获得大量项 但是,在循环的下一次迭代中,IQueryable.ToList()给了我0项 这让我快发疯了。我尝试

我很困惑

我正在使用VB.Net、Linq和DataContext。My DataContext包含一个表“transactions”

我首先声明一个IQueryable(事务的),并将其赋值为nothing。我在foreach循环中构建了一个谓词,并使用transactions.Where(谓词)为IQueryable赋值。如果执行IQueryable.ToList(),则会在集合中获得大量项

但是,在循环的下一次迭代中,IQueryable.ToList()给了我0项

这让我快发疯了。我尝试在VS2010中使用LINQ to SQL调试可视化工具(我用新的引用重新编译了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
    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

我不太熟悉PredicateBuilder,但我认为您正在捕获(结束)那里的
chosenCode
变量

这意味着您的
testRun3
将填充该运行的选择代码,但在下一次迭代中,testRun将填充新的选择代码


解决方案很简单,在下一步之前执行
groupQuery=groupQuery.ToList()

我怀疑
groupQuery.Union(vf.transactions.Where(codePredicate))
可能正在生成不返回任何记录的sql。您可能希望在ManagementStudio中执行相同的查询

谢谢你的意见!我真的很想把旧的选择码和新的选择码结合起来。此外,如果执行“ToList()”,恐怕查询将执行,从而导致对SQL Server的不必要调用。我错了吗?这可能是一个简化代码的人工制品,但它看起来像是一个非常复杂的方式,导致了一次又一次的执行。哦,老兄。我知道的很少。我不知道什么是一次又一次的处决。不过,我可以解释情况。foreach的每次迭代都会构建一个插入到查询中的动态谓词。每个查询都合并在一起。然后在外部foreach中,该联合查询首先分组,然后与其他同类查询联合。然后,再次对其进行筛选,最后对其进行分组。此外,当我添加groupQuery=groupQuery.ToList()时,出现错误“无法将'System.Collections.Generic.List
1[transaction]'类型的对象强制转换为'System.Linq.IQueryable
1[transaction]”。太棒了!最后我尝试了一下,发现我需要使用“Concat()”(UNION和UNION-ALL之间的SQL差异)。