您应该首先分析由实体框架实际发出的SQL命令。根据您的配置(POCO,自我跟踪实体),还有很大的优化空间。您可以使用ObjectSet<T>.ToTraceString()
方法来调试SQL命令(在调试和发布模式之间不应有区别)。如果遇到需要进一步优化的查询,则可以使用一些预测为EF提供有关您要完成的工作的更多信息。
例:
Product product = db.Products.SingleOrDefault(p => p.Id == 10);
// executes SELECT * FROM Products WHERE Id = 10
ProductDto dto = new ProductDto();
foreach (Category category in product.Categories)
// executes SELECT * FROM Categories WHERE ProductId = 10
{
dto.Categories.Add(new CategoryDto { Name = category.Name });
}
可以替换为:
var query = from p in db.Products
where p.Id == 10
select new
{
p.Name,
Categories = from c in p.Categories select c.Name
};
ProductDto dto = new ProductDto();
foreach (var categoryName in query.Single().Categories)
// Executes SELECT p.Id, c.Name FROM Products as p, Categories as c WHERE p.Id = 10 AND p.Id = c.ProductId
{
dto.Categories.Add(new CategoryDto { Name = categoryName });
}
我只是在脑子里打了一下,所以这并不是它的执行方式,但是如果您将查询的所有知识告诉EF,EF实际上会做一些不错的优化(在这种情况下,我们将需要以下类别:名称)。但这不像急切加载(db.Products.Include(“ Categories”)),因为投影可以进一步减少要加载的数据量。