当从 linq 查询创建 IQueryable 时,为什么它不是一个“新”查询?多变的?
我正在使用实体框架,并有一个循环查看一组人员,并使用 foreach 循环创建每个人地址的查询。创建每个地址查询时,它都会添加到树视图的节点中,稍后可以使用它(以填充子节点):
IQueryable<Person> pQuery = (IQueryable<Person>)myContext.People; //get a list of people
//go through and get the set of addresses for each person
foreach (var p in pQuery)
{
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)
TreeNode newNode = new TreeNode();
newNode.Tag = addressQuery;
}
现在,我在运行应用程序时发现的问题是所有查询都是最后创建的查询即循环的最后一次迭代。这就像在循环的第一次迭代中创建addressQuery,然后在每个后续查询中覆盖它。这样做的结果是,树节点中的所有地址查询都是对最后一个查询的引用(?)
进一步调查,我可以通过使用静态类生成地址查询并将其传递到每个TreeNode,如下:
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;
}
}
我的问题是我对这种行为感到困惑。为什么静态查询类对我有帮助?谁能向我解释这是怎么回事?
困惑.com!
I am using the Entity Framework and have got a loop that looks at a set of People and using a foreach loop creates a query for the address of each person. As each address query is created it is added to the node of a treeview where it can be later used (to populate children nodes):
IQueryable<Person> pQuery = (IQueryable<Person>)myContext.People; //get a list of people
//go through and get the set of addresses for each person
foreach (var p in pQuery)
{
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)
TreeNode newNode = new TreeNode();
newNode.Tag = addressQuery;
}
Now, the problem that I am finding upon running the app is that ALL the queries are the last query created i.e. the last iteration of the loop. It is like the addressQuery is created on the first iteration of the loop and then overwritten on each subsequent query. The result of this is that it is like all the address queries in the treenodes are references to the last query made(?)
Further investigation that I could solve the problem by using a static class to generate the address query and pass that into each the TreeNode, as follows:
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;
}
}
The question I have is that I am baffled by this behaviour. Why does having a static query class help me? Can anyone explain to me what is going on?
Confused.Com!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
原因是
p
变量(foreach
循环变量)被捕获并且查询被延迟计算。因此,当查询实际运行时,它使用当时p
变量的当前值,即最后一个值。阅读我对“a的确切定义是什么”的回答关闭?” 了解更多信息。要解决这个问题,只需尝试引入一个临时变量:
The reason is that the
p
variable (theforeach
loop variable) is captured and the query is evaluated lazily. As a result, when the query is actually run, it uses the current value ofp
variable at that time, which is the last value. Read my answer to "What is the exact definition of a closure?" for more info.To solve the problem, simply try introducing a temporary variable: