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

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!

于 2012-10-05T20:20:34.773 回答
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();
}
于 2012-09-24T06:07:53.933 回答