Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq to EF Join throws "Index was out of range" after upgrade from VS2010 to VS2012

After upgrading from Visual Studio 2010 to 2012 code started throwing "ArgumentOutOfRangeException - Index was out of range. Must be non-negative and less than the size of the collection.Parameter name: index" on Linq queries using Joins.

The following simple example made in LINQPad (using an EF data model) gives me the 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(); 
}

Changing the previous example to return an anonymous object containing both sides of the join doesn't give the ArgumentOutOfRangeException and gives results as expected:

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(); 
}

Ok, so for some reason I had to return both sides of the join, but then I tried the following example using a dummy value instead, that also executed without a problem:

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(); 
} 

Taking the first example and adding a ToList() to the first query also makes it execute without a problem:

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(); 
}

Important: Trying the first query on a workstation without the Visual Studio 2012 upgrade works fine!

Can anyone confirm/explain this new "feature"? :-)

like image 739
Erwin Avatar asked Sep 19 '12 06:09

Erwin


2 Answers

Erwin, just to close the loop on this: We have confirmed that it is a bug we introduced recently in LINQ to Entities and we are looking at ways to get a fix out. Thanks a lot for reporting it!

like image 104
divega Avatar answered Oct 20 '22 07:10

divega


After giving this some more investigation, I've come to the conclusion that the problem is the anonymous class I'm returning from the Linq query, I think it isn't allowed anymore to return an anonymous class with only one field in it, I know it isn't needed to wrap the field in an anonymous class but ... as I said this worked before upgrading.

Following example gives me the "ArgumentOutOfRangeException - Index was out of range":

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();
}

this next example works as expected:

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();
}
like image 41
Erwin Avatar answered Oct 20 '22 09:10

Erwin