Entity Framework 运行 数据库是否再次查询已经 运行 的查询?

Does Entity Framework run database query again for already run query?

我正在使用 Entity Framework 代码优先方法开发一个 Asp.Net mvc 项目。但我正在努力提高我的应用程序的性能。我不清楚如果我再次访问相同的条件,Entity Framework 运行 数据库是否再次查询。

这是我的代码:

var item = context.Items.FirstOrDefault();// Database query will be run for this
var start = item.Promotions.FirstOrDefault().Start; // Another query will be run for this
var end = item.Promotions.FirstOrDefault().End; //Will another query be run again? Same query is run again for this
var price = item.Promotions.FirstOrDefault().Price; //Here also

如您在代码中所见,新查询将 运行 检索促销开始日期。但是当我检索结束日期时,数据库将再次 运行 查询,即使它们是相同的查询。我对此感到困惑。

数据库中的数据在此期间可能已更改,这就是为什么 EF 再次 运行 查询。

为了提高性能,只需自己缓存结果:

var item = context.Items.FirstOrDefault(); // Database query will be run for this
var promotion = item.Promotions.FirstOrDefault(); // Another query will be run for this
var start = promotion.Start; // No additional query
var end = promotion.End;     // No additional query
var price = promotion.Price; // No additional query

顺便说一句:这与延迟加载无关。延迟加载与延迟加载它引用的其他实体有关。与其数据无关

虽然答案是正确的,但还有另一种选择需要考虑

您的原始查询

var item = context.Items.FirstOrDefault();// Database query will be run for this
var start = item.Promotions.FirstOrDefault().Start; // Another query will be run for this
var end = item.Promotions.FirstOrDefault().End; //Will another query be run again? Same query is run again for this
var price = item.Promotions.FirstOrDefault().Price; //Here also

作为对象加载项停止从对象读取数据

var item = context.Items.FirstOrDefault();// Database query will be run for 

现在加载的所有对象都保存在内存中,无需生成查询即可读取

item.Description 
item.Items //etc

现在懒加载时获取数据是 变量提升 = item.Promotions.FirstOrDefault() 这将产生另一个查询

promotion.Start
promotion.End

问题是,如果您每次都阅读提升,最好将其包含在查询中(使用预先加载),这样当获取对象时,它会加载子对象

var item = context.Items.Include(x=>x.Promotions).FirstOrDefault();

然后只需向数据库查询一次即可获取有关商品和促销的数据。

特异性select离子

您还可以将查询更新为 select 只有您感兴趣的项目,方法是:

var customObj = context.Promotions.Where(p=>p.ItemId==itemId).Select(x=>new{x.Start, x.End, x.Price}).FirstOrDefault();

这样您将收到特定的 select 并且它会为您生成特定的查询。

备注 使用 sql profiler / ants profiler 等查看你生成的sql。