12

Visual Studio 2010から2012にアップグレードした後、コードは、結合を使用するLinqクエリで「ArgumentOutOfRangeException-インデックスが範囲外でした。負ではなく、コレクションのサイズ未満である必要があります。パラメーター名:インデックス」のスローを開始しました。

LINQPadで作成された次の簡単な例(EFデータモデルを使用)では、ArgumentOutOfRangeExceptionが発生します。

void Main()
{
    var iq1 = Customers.Select(ap => ap.ID);
    var iq2 = iq1.Join(Customers.Select(ap => ap.ID),
                    a => a,
                    b => b,
                    (a, b) => new { a });

    iq2.Dump(); 
}

結合の両側を含む匿名オブジェクトを返すように前の例を変更しても、ArgumentOutOfRangeExceptionは発生せず、期待どおりの結果が得られます。

void Main()
{
    var iq1 = ActionPlans.Select(ap => ap.ID);
    var iq2 = iq1.Join(ActionPlans.Select(ap => ap.ID),
                    a => a,
                    b => b,
                    (a, b) => new { a, b });

    iq2.Dump(); 
}

さて、何らかの理由で結合の両側を返す必要がありましたが、代わりにダミー値を使用して次の例を試しましたが、これも問題なく実行されました。

void Main()
{
    var iq1 = ActionPlans.Select(ap => ap.ID);
    var iq2 = iq1.Join(ActionPlans.Select(ap => ap.ID),
                    a => a,
                    b => b,
                    (a, b) => new { a, x = 1 });

    iq2.Dump(); 
} 

最初の例を取り上げ、最初のクエリにToList()を追加すると、問題なく実行されます。

void Main()
{
    var iq1 = ActionPlans.Select(ap => ap.ID).ToList();
    var iq2 = iq1.Join(ActionPlans.Select(ap => ap.ID),
                    a => a,
                    b => b,
                    (a, b) => new { a });

    iq2.Dump(); 
}

重要: Visual Studio 2012をアップグレードせずにワークステーションで最初のクエリを試行すると、正常に機能します。

誰かがこの新しい「機能」を確認/説明できますか?:-)

4

2 に答える 2

6

アーウィン、これについてループを閉じるだけです。これは、LINQ to Entities で最近導入したバグであることを確認しており、修正する方法を検討しています。報告してくれてどうもありがとう!

于 2012-10-05T20:20:34.773 に答える
4

これをさらに調査した後、問題はLinqクエリから返された匿名クラスであるという結論に達しました。フィールドが1つしかない匿名クラスを返すことはもう許可されていないと思います。フィールドを匿名クラスでラップする必要がないことはわかっていますが...アップグレード前にこれが機能したと言ったように。

次の例では、「ArgumentOutOfRangeException - インデックスが範囲外でした」というメッセージが表示されます。

void Main()
{
    var iq1 = ActionPlans.Select(ap => ap.ID).ToList();
    var iq2 = iq1.Join(ActionPlans.Select(ap => ap.ID),
                    a => a,
                    b => b,
                    (a, b) => new { a });

    iq2.Dump();
}

この次の例は期待どおりに機能します。

void Main()
{
    var iq1 = ActionPlans.Select(ap => ap.ID).ToList();
    var iq2 = iq1.Join(ActionPlans.Select(ap => ap.ID),
                    a => a,
                    b => b,
                    (a, b) => a );

    iq2.Dump();
}
于 2012-09-24T06:07:53.933 に答える