我有这堂课:
public class Product {
[NotMapped]
public bool Recommended {get;set;}
public int ID {get;set;}
//Other stuff
}
然后我从数据库中获取它们并分配推荐变量。我现在已经将它们全部设置为真,而我测试并且有效。
var Products = Find(SearchParams, DataContext).ToList();
foreach(var product in Products) {
product.Recommended = true;
if (!product.Recommended) throw new Exception();
}
好的,它有效,我们通过了。
然后我去做一组结果,看起来像这样:
public class QuoteProduct {
public Product Product {get;set;}
public Quote Quote {get;set;}
//etc
}
分配产品:
var Results = new List<QuoteProduct>();
foreach(var product in Products) {
var entry = new QuoteProduct(){
Product = product;
Quote = getQuote(this);
}
if (!entry.Product.Recommended) throw new Exception();
Results.add(entry);
}
并且总是抛出异常!为什么?即使,就在我之前:
entry.Product.Recommended = true;
if (!entry.Product.Reccomended) throw new Exception();
答案 0 :(得分:2)
懒惰的评估问题
Find(SearchParams, DataContext);
可能会返回IEnumerable<>
,因此每次迭代它时,都会生成新的Product
类。这使得product.Recommended = true;
无用。
这里:
var Products = Find(SearchParams, DataContext);
foreach(var product in Products) // <--- here it's iterated and new classes instantiated
{
product.Recommended = true;
if (!product.Recommended) throw new Exception();
}
,此处:
var Results = new List<QuoteProduct>();
foreach(var product in Products) // <-- and here are new classes instantiated
// So your previous `product.Recommended = true;` is gone!
{
var entry = new QuoteProduct(){
Product = product;
Quote = getQuote(this);
}
if (!entry.Product.Recommended) throw new Exception();
Results.add(entry);
}
您可以使用以下方法修复此问题:
// The key is to persist the data with (for example) ToArray() or ToList()
var Products = Find(SearchParams, DataContext).ToArray();
坚持不懈的缺点是,所有行都是&#39;被同时加载到内存中。 (这是懒惰评估有用的原因)