我正在尝试做我认为简单的事情,但我怀疑我太难以知道我可能做错了什么.我有一个LINQ查询返回:
IQueryableResult
CWords是一个类,我定义如下:
public class CWords { public CWords(){} public string _column1{ get; set; } public float _column2{ get; set; } public void fixData(){} }
在我的代码中,我试图修改Result的每个成员的_column2字段.我试过了:
foreach (CWords item in Result) { item.fixData(); }
但当然这不起作用.item不在适当的范围内,因此我在fixData中所做的任何更改都没有在Result中.
因为你无法索引IQueryable,我的解决方法是执行以下操作:
var items = goodWords.ToList(); for (int i = 0; i < items.Count(); i++ ) { items[i].fixData(); }
这是正确的方法吗?
Brandon,使用LINQ时这是一个正常的错误.请注意,从LINQ返回的IQueryable实际上并不包含您的项目,这就是您无法将其编入索引的原因.当您实际请求项目时,它只有足够的信息来执行查询.这称为" 延迟执行 ",因为查询不会在您select
(但稍后)枚举结果时执行.您可以搜索"linq延迟执行"并找到许多人试图解释它是如何工作的.
执行此操作时foreach
,查询将运行,并且您正在按照预期在每个项目上调用fixData().但是,当您再次访问IQueryable时,您将再次执行查询,并且(取决于您使用的LINQ提供程序)您可能会再次引入原始未修改的项目.
通过调用IQueryable上的ToList(),您将创建一个包含查询所有结果的内存列表.您现在可以索引到此列表并访问它,而无需再次执行查询.如果您可以将所有项目都放在内存中(小结果集),那么使用ToList()可能是一个很好的解决方案.
@PaulG,你是对的,他可以使用foreach
而不是for
,但他应该保存对列表的引用,否则他就在他开始的地方(使用IQueryable).
var items = goodWords.ToList(); foreach (var item in items) { item.fixData(); }