2015-04-02 5 views
1

я следующее:IQueryable и граф

IQueryable<ViewAccountEntry> viewAccountEntries = db.AccountEntries 
    .Where(x => x.DEntryID == 0) 
    .Select(x => new ViewAccountEntry() 
    { 
     AccountEntry = x, 
     DAccountEntries = db.AccountEntries 
      .Where(y => y.DEntryID == 0 
       && y.Amount == -x.Amount 
       && y.DateEntry == x.DateEntry) 
      .ToList() 
    }); 
    Pages = new PageInfo(viewAccountEntries.Count(), page); 
    ViewAccountEntries = viewAccountEntries 
     .OrderBy(x => x.AccountEntry.DateEntry) 
     .Skip(Pages.ItemsSkipped) 
     .Take(Pages.ItemsPerPage) 
     .ToList(); 

Внутри первого Select() объект создается, содержащий второй список.

Когда выполняется .Count(), выполняется ли его выборка Select? Или он рассчитывает разумно, зная, что ему не нужно выполнять либо Select?

+5

Запишите фактический выполняемый SQL (и профиль базы данных, если только это не дает вам ответа) и узнайте сами. – Servy

+0

Не знаю, как это сделать. – CapIsland

+3

Теперь самое время учиться. Вы должны проверять SQL большинства запросов LINQ, которые вы когда-либо пишете (по крайней мере, на каких-либо сложных), чтобы проверить вашу работу и убедиться, что ничего скрытного не происходит за кулисами. Что касается того, как это будет зависеть от поставщика запросов, но каждый из них будет раскрывать способы его регистрации. То же самое можно сказать о проверке подробного плана выполнения запроса на конец базы данных; найдите свою конкретную базу данных. – Servy

ответ

3

Count() превращен в лучшую реализацию Count(), о которой знает механизм запросов.

Механизмы запросов базы данных, такие как Entity Framework или Linq2SQL, обычно используют что-то, что вызывает COUNT(*), COUNT(DISTINCT some_field) или аналогичные, которые будут использоваться в произведенном SQL.

Другие реализации linq аналогичным образом попытаются быть настолько умными, насколько это возможно. Например, linq-to-objects будут вызывать Count геттер, а не перечислять через всю нумерацию, если он вызван на объект, который реализует ICollection или ICollection<T>.

Возможно, что данный механизм запросов при работе с данным использованием Count() в конечном итоге должен пройти цикл перечисления элементов, поскольку он не может определить ничего более эффективного. Как правило, чем больше вы держите вещи на терминах начального типа Linq (например, не звоните ToList(), если вам не нужно, или даже AsEnumerable(), если вам это не удастся), тем лучше будет делать движок, хотя иногда бывают исключения.

1

До тех пор, пока вы держите его IQueryable и не звоните ToList(), EF достаточно умен, чтобы оптимизировать запрос и предотвратить любой фактический выбор по запросу Count().