您应该从分析实体框架实际发出的SQL命令开始.根据您的配置(POCO,Self-Tracking Entities),有很大的优化空间.您可以使用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实际上做了一些很好的优化.但这与Eager 加载(db.Products.Include("类别"))不同,因为投影可以进一步减少要加载的数据量.