.net Linq到EF连接抛出”;指数超出范围”;从VS2010升级到VS2012后

.net Linq到EF连接抛出”;指数超出范围”;从VS2010升级到VS2012后,.net,linq,entity-framework,exception,visual-studio-2012,.net,Linq,Entity Framework,Exception,Visual Studio 2012,从Visual Studio 2010升级到2012后,代码开始在使用联接的Linq查询上抛出“ArgumentOutOfRangeException-索引超出范围。必须为非负且小于集合大小。参数名称:索引” 以下在LINQPad中制作的简单示例(使用EF数据模型)为我提供了ArgumentOutOfRangeException: void Main() { var iq1 = Customers.Select(ap => ap.ID); var iq2 = iq1.Joi

从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).ToList();
    var iq2 = iq1.Join(ActionPlans.Select(ap => ap.ID),
                    a => a,
                    b => b,
                    (a, b) => a );

    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(); 
} 
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(); 
}
以第一个示例为例,在第一个查询中添加一个ToList(),也可以使其顺利执行:

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(); 
} 
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升级的工作站上尝试第一个查询可以正常工作


谁能确认/解释这个新的“功能”?:-)

在进行了更多的调查之后,我得出结论,问题在于我从Linq查询返回的匿名类,我认为不再允许返回只有一个字段的匿名类,我知道不需要将字段封装在匿名类中,但是。。。正如我所说,这在升级之前起作用

下面的示例给出了“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).ToList();
    var iq2 = iq1.Join(ActionPlans.Select(ap => ap.ID),
                    a => a,
                    b => b,
                    (a, b) => a );

    iq2.Dump();
}

Erwin,结束这个循环:我们已经确认这是我们最近在LINQ中向实体引入的一个bug,我们正在寻找解决方法。非常感谢您的报道

此错误已提交到。如果你能复制它,那么告诉微软。如果某个补丁对你很重要,那么在那里“向上投票”。嘿@divenga。。有关于这个问题的更新吗?我们的整个项目在团队升级到VS2012后停止!我们正在努力修复这个bug,还有其他几个bug。我不确定这是否合理,但正如您所发现的,向匿名类型添加第二个虚拟属性可以解决此问题。嘿@alaasdk您可以通过Microsoft.com的netfx45compat与我们联系吗?我想帮助您的团队解锁。现在似乎已修复: