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。
我正在使用 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。