我有下面的BL方法
public static void SomeMethod (List<SomeClass> group)
{
IEnumerable<SomeClass> groupWithFalse =(from SomeClass gr in group
where gr.SomeProp== false
select gr);
foreach (SomeClass grFalse in groupWithFalse)
{
grFalse.Save();
}
if (groupWithFalse.Any())
{
// do some stuff
}
}保存dl的模拟实现(不能更改,因为它在许多单元测试中使用)是:
public void Save()
{
group.SomeProp = true;
}如果我尝试单元测试流的最后一条语句,例如If (groupWithFalse.Any()),语句将失败,因为显然没有更多的元素将该属性设置为false。如果我将业务逻辑中的代码更改为:
public static void SomeMethod (List<SomeClass> group)
{
List<SomeClass> groupWithFalse = new List<SomeClass>();
foreach (var g in group)
{
if (g.SomeProp == false)
groupWithFalse.Add(g);
}
foreach (SomeClass grFalse in groupWithFalse)
{
grFalse.Save();
}
if (groupWithFalse.Any())
{
// do some stuff
}
}条件语句if (groupWithFalse.Any())在单元测试中不会失败。这一切为什么要发生?谢谢
发布于 2010-12-21 04:19:58
运行LINQ查询不会存储结果。
相反,它将在您每次枚举该查询时重新执行该查询。
调用Save()之后,查询将为空,因为没有一个条目满足where子句。
将其更改为
var unsaved = group.Where(g => !g.SomeProp).ToList();调用ToList()会将结果存储在List<T>中;这可以避免重新执行查询。
发布于 2010-12-21 04:20:41
您的问题是由于deferred execution而发生的。在您的第一个示例中,groupWithFalse并不表示SomeProp为false的对象列表,它引用了一个可以计算出该列表的查询。
如果你想让你的列表在整个函数中保持不变,只需在LINQ查询的末尾添加.ToList(),如下所示:
IEnumerable<SomeClass> groupWithFalse =(from SomeClass gr in group
where gr.SomeProp == false
select gr).ToList();
// ^^^^^^^^^ 这将导致查询立即执行,并将其结果返回到一个List<SomeClass>中,如果您修改其中的对象,它的内容将不会更改。
发布于 2010-12-21 04:20:11
你的问题出在LINQ的Lazy Evalution上。在第一个示例中,LINQ查询实际上运行了两次。第一个用于枚举调用Save()方法,第二个用于获取Any()。
使用LINQ时的一般规则是,在每个查询之后放入ToList()。
https://stackoverflow.com/questions/4493484
复制相似问题