当从linq查询创建IQueryable时,为什么它不是一个";新";变量

当从linq查询创建IQueryable时,为什么它不是一个";新";变量,linq,entity-framework,byref,Linq,Entity Framework,Byref,我使用的是实体框架,有一个循环可以查看一组人,使用foreach循环可以创建每个人地址的查询。创建每个地址查询时,都会将其添加到树视图的节点中,以便以后使用(填充子节点): IQueryable pQuery=(IQueryable)myContext.People//获取一份人员列表 //浏览并获取每个人的地址集 foreach(pQuery中的var p) { var addressQuery=来自myContext.Addresses中的 来自a.Address\u链接中的al 其中al.

我使用的是实体框架,有一个循环可以查看一组人,使用foreach循环可以创建每个人地址的查询。创建每个地址查询时,都会将其添加到树视图的节点中,以便以后使用(填充子节点):

IQueryable pQuery=(IQueryable)myContext.People//获取一份人员列表
//浏览并获取每个人的地址集
foreach(pQuery中的var p)
{
var addressQuery=来自myContext.Addresses中的
来自a.Address\u链接中的al
其中al.P_ID==P.P_ID
订购者a.a\U邮政编码
选择一个;
//将查询添加到TreeView节点(使用标记存储查询)
TreeNode newNode=新的TreeNode();
Tag=addressQuery;
}
现在,我在运行应用程序时发现的问题是,所有查询都是创建的最后一个查询,即循环的最后一次迭代。这就像在循环的第一次迭代中创建addressQuery,然后在每个后续查询中覆盖它一样。其结果是,树节点中的所有地址查询都是对上一次查询的引用(?)

进一步调查表明,我可以通过使用静态类生成地址查询并将其传递到每个树节点来解决问题,如下所示:

 public static class Queries
    {
        public static IQueryable<Address> AddressesForPerson(GenesisEntities myContext, int key)
        {
            var query = from a in myContext.Addresses
                        from al in a.Address_Links
                        where al.P_ID == key
                        orderby a.A_POST_CODE
                        select a;
            return query;
        }

}
公共静态类查询
{
公共静态可查询地址ForPerson(GenesisEntities myContext,int key)
{
var query=来自myContext.Addresses中的
来自a.Address\u链接中的al
其中al.P_ID==键
订购者a.a\U邮政编码
选择一个;
返回查询;
}
}
我的问题是,我对这种行为感到困惑。为什么静态查询类对我有帮助?有人能向我解释一下发生了什么事吗


困惑网

原因是捕获了
p
变量(
foreach
循环变量),并且延迟计算查询。因此,当查询实际运行时,它使用当时
p
变量的当前值,这是最后一个值。阅读更多信息

要解决此问题,只需尝试引入一个临时变量:

 // `loopVariable` is scoped inside loop body AND the loop declaration.
 foreach (var loopVariable in pQuery) 
 {
      var p = loopVariable; // This variable is scoped **inside** loop body.
      var addressQuery = from a in myContext.Addresses
                                   from al in a.Address_Links
                                   where al.P_ID == p.P_ID
                                   orderby a.A_POST_CODE
                                   select a;


     //add the query to a TreeView node (use the tag to store it)
     myTreeView.Tag = addressQuery
 }

哇!这是一个该死的抓到你了!谢谢Mehrdad
 // `loopVariable` is scoped inside loop body AND the loop declaration.
 foreach (var loopVariable in pQuery) 
 {
      var p = loopVariable; // This variable is scoped **inside** loop body.
      var addressQuery = from a in myContext.Addresses
                                   from al in a.Address_Links
                                   where al.P_ID == p.P_ID
                                   orderby a.A_POST_CODE
                                   select a;


     //add the query to a TreeView node (use the tag to store it)
     myTreeView.Tag = addressQuery
 }