Entity Framework и проблема производительности Linq - PullRequest
1 голос
/ 01 сентября 2010

У меня проблема с производительностью Entity Framework и Linq при просмотре списка объектов Product:

var data =_service.GetAll(); 
var page = data.Skip((index) * pageSize).Take(pageSize);
list.Add(page.AsEnumerable); // ** its slow right here

В моей тестовой базе данных содержится 1958 продуктов, но при выполнении приведенного выше кода я вижу 3916 (то есть 1958 * 2) отдельных выполненных запросов (глядя на профилировщик SQL).

Класс Product выглядит примерно так:

public class Product 
{
    public virtual int Id {get;set;}
    public virtual string ProductCode {get;set;}
    //..etc other properties
    public virtual ICollection<WarehouseProduct> WarehouseProducts { // etc }
    public virtual ICollection<InvoiceLine> InvoiceLines { // etc }
    // etc other navigation properties
}

В профиле SQL Server я вижу этот запрос, выполненный 3916 раз:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[ProductId] AS [ProductId], 
// etc
FROM [dbo].[WarehouseProducts] AS [Extent1]

Что я сделал не так? Объект Product имеет 12 различных свойств навигации, но только WarehouseProduct был запрошен 3916 раз. Обратите внимание, что в этом запросе нет предложения WHERE, но между двумя таблицами существует отношение внешнего ключа (поэтому это свойство навигации)

Ответы [ 2 ]

3 голосов
/ 01 сентября 2010

Вы должны получить доступ к Product.WarehouseProducts после того, как получите продукты, поэтому, если вы используете Entities, вы хотите использовать Products.Include("WarehouseProduct").Include("InvoiceLine") в своем методе GetAll(), который сообщит Entities для получения данных в том же запросе..

Связанные объекты по умолчанию загружаются с отложенной загрузкой, поэтому, если вы не используете Include(), чтобы указать, какие связанные объекты следует включить в ваши результаты, то каждый раз, когда вы получаете доступ к связанной сущности в своем коде, вывызовет другой поиск в базе данных.

0 голосов
/ 10 сентября 2014

page.AsEnumerable вызывает оценку и материализацию запрашиваемой последовательности. Предыдущие операторы, предполагая, что отложенная загрузка по-прежнему включена, и вы запрашиваете источник данных SQL, задают условия, из-за которых будет выполняться оператор SQL.

Вы не опубликовали метод GetAll (), так что это может быть источником ваших дополнительных записей.

Сгенерированный SQL-запрос должен иметь TOP как часть выбора, и он должен возвращать набор результатов с несколькими записями, поэтому, возможно, вы не профилируете правильный запрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...