2

私は困惑しています。

VB.Net、Linq、およびDataContextを使用しています。私のDataContextにはテーブル'transactions'が含まれています。

最初にIQueryable(Ofトランザクション)を宣言し、それを何にも割り当てません。foreachループで述語を作成し、transactions.Where(predicate)を使用してIQueryableに値を割り当てます。IQueryable.ToList()を実行すると、コレクション内のいくつかのアイテムを取得します。

ただし、ループの次の反復で、IQueryable.ToList()は0個のアイテムを返します。

これは私を夢中にさせています。VS2010でLINQtoSQL 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) のは、コードでさらに2、3回変換するまで、クエリを実行しないことです。混乱させて申し訳ありません。

回答の編集: 私が受け取った回答は両方とも、最終的な解決策に貢献しました。ToList()結局、各反復を呼び出すことと、Concat()の代わりにを使用することの両方になりUnion()ました。実行するたびに、生成されたSQLにはその反復のUnion()パラメーター()が含まれることがわかりました。クエリを実行するまでに、生成されたSQLに10セットまたは20セットのパラメーター(の反復ごとに1セット)が含まれている可能性がありますが、実行時にSQLServerに提供されたパラメーターは最終セットのみでした。理由を聞かないでください。これは証明されていません。実験による結論にすぎません。これを理解すると、渡されるすべてのパラメーターを取得する方法を理解できませんでした。だから、私はあきらめて、SQLServerへのクエリを@variablechosenCodechosenCodechosenCode。完全にビルドされるまで、クエリを実行せずにそれを行う方法を知りたいのですが。

に取り組む代わりにIQueryable、強い型を使用しList(Of transaction)ての結果を保存しますToList()。次に、残りのコード全体でLinqtoObjectsを使用してそのリストを操作します。

Union()また、を使用するUNIONと、生成されたSQLでステートメントが生成されることもわかりましたが、期待した結果が得られませんでした。そこで、生成されたSQLでステートメントConcat()を生成するを使用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
4

2 に答える 2

1

私はPredicateBuilderに精通していませんが、chosenCodeそこで変数をキャプチャ(クローズ)していると思います。

つまり、あなたtestRun3はその実行のchosenCodeで満たされますが、次の反復では、testRunは新しいchosenCodeで満たされます。

解決策は簡単です。そのgroupQuery = groupQuery.ToList()直前に実行してくださいNext

于 2012-04-15T20:17:14.143 に答える
0

groupQuery.Union(vf.transactions.Where(codePredicate))レコードを返さないSQLを生成している可能性があります。ManagementStudioで同じクエリを実行することをお勧めします。

于 2012-04-16T05:40:23.127 に答える