从Visual Studio 2010升级到2012后,代码开始抛出“ArgumentOutOfRangeException - 索引超出范围。必须是非负的且小于集合的大小。参数名称:索引”在Linq查询上使用连接。
以下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升级的情况下在工作站上尝试第一个查询工作正常!
任何人都可以确认/解释这个新的“功能”吗? : - )
答案 0 :(得分:6)
答案 1 :(得分:4)
在进行了更多的调查之后,我得出结论,问题是我从Linq查询返回的匿名类,我认为不再允许返回只有一个字段的匿名类在其中,我知道不需要将字段包装在匿名类中,但是...正如我在升级之前所说的那样。
以下示例给出了“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();
}