简体   繁体   English

从VS2010升级到VS2012后,Linq到EF加入“索引超出范围”

[英]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. 从Visual Studio 2010升级到2012后,代码开始抛出“ArgumentOutOfRangeException - 索引超出范围。必须是非负的且小于集合的大小。参数名称:索引”在使用联接的Linq查询上。

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

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: 更改前面的示例以返回包含连接两边的匿名对象不会给出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(); 
}

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: 采用第一个示例并将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(); 
}

Important: Trying the first query on a workstation without the Visual Studio 2012 upgrade works fine! 重要说明:在没有Visual Studio 2012升级的情况下在工作站上尝试第一个查询工作正常!

Can anyone confirm/explain this new "feature"? 任何人都可以确认/解释这个新的“功能”吗? :-) :-)

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. Erwin,只是为了关闭这个循环:我们已经确认这是我们最近在LINQ to Entities中引入的一个错误,我们正在寻找解决问题的方法。 Thanks a lot for reporting it! 非常感谢报道!

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. 在进行了更多调查之后,我得出结论,问题是我从Linq查询返回的匿名类,我认为不再允许返回一个只包含一个字段的匿名类,我知道不需要将字段包装在一个匿名类中,但是...正如我所说的那样在升级之前有效。

Following example gives me the "ArgumentOutOfRangeException - Index was out of range": 下面的例子给我“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();
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM