2016-10-18 3 views
1

Я создал панель управления, в которой все данные, отображаемые на ней, имеют 4 общих элемента (startDate, endDate, CompanyID, StoreID), которые используются как предложения Where в инструкции Linq. В результате этого заявления затем запрашивается в различных способов группировки и сортировки данных и используются в диаграммах, списки и т.д. Вот краткое Snippit, чтобы показать, что дублирование в настоящее время происходит:Выполнение нескольких запросов Linq в отношении того же результата Linq

var dashboardEntity = new BlueStreakSalesDWEntities(); 

    //Get Total Sales 
ViewBag.companySalesTotal = dashboardEntity.FactSales.Where(d => d.DateKey >= startDate) 
                .Where(d => d.DateKey <= endDate) 
                .Where(c => c.CompanyID == companyID) 
                .Sum(a => a.Amount); 

//get list of all items sold 
var companyStoreTotalItem = dashboardEntity.FactSales.Where(d => d.DateKey >= startDate) 
              .Where(d => d.DateKey <= endDate) 
              .Where(c => c.CompanyID == companyID).GroupBy(m => new { m.Description }) 
              .Select(g => new DescriptionAmountModel { Amount = g.Sum(a => a.Amount).Value, Description = g.Key.Description }) 
              .OrderByDescending(x => x.Amount); 

I имеют 15 таких вызовов на панели управления, и это может быть очень медленным в разы, из того, что я себе представляю, - это несколько вызовов, когда на самом деле нужно только запрашивать базу данных только тогда, когда этот результат должен быть запрошен для разных результатов.

Как это сделать?

Любая помощь будет высоко оценена

ответ

2

В текущем решении каждый запрос выполняется раздельно, на одних и тех же данных. Сначала вы можете выполнить общие части запросов и принести результаты из базы данных. В ваших примерах эти where условие

//Executes in database 
var entities = dashboardEntity.FactSales.Where(d => d.DateKey >= startDate) 
             .Where(d => d.DateKey <= endDate) 
             .Where(c => c.CompanyID == companyID) 
             .ToList(); 

Теперь, когда эти данные фильтруются только то, что вы хотите, вы можете в памяти сделать остальную часть агрегатов:

//Happens in the List<T> in memory 
ViewBag.companySalesTotal = entities.Sum(a => a.Amount); 

var companyStoreTotalItem = entities.GroupBy(m => new { m.Description }) 
            .Select(g => new DescriptionAmountModel { Amount = g.Sum(a => a.Amount).Value, Description = g.Key.Description }) 
            .OrderByDescending(x => x.Amount); 
+1

Спасибо, что имеет смысл. – Nate58

+0

@NateGreene - приветствую :) вы также можете поместить все условия 'where' в ту же функцию' Where' с помощью оператора '&&'. Будет переводить на тот же самый sql, но может выглядеть немного чистым. –

+1

Вы не можете выполнять задачи сущности-структуры параллельно с одним контекстом. Вы ничего не получаете от запросов в объектах памяти, использующих задачи async/wait. –

0

Таким образом, вы можете сделать эффективными , Это заставляет запрос выполнять однократное время в базе данных, а остальная часть части происходит при извлечении данных в памяти.

var result = dashboardEntity.FactSales.Where(d => d.DateKey >= startDate && d => d.DateKey <= endDate && d.CompanyID == companyID).ToList(); 

ViewBag.companySalesTotal = result.Sum(a => a.Amount); 

//then get list of all items sold from in memory data 
var companyStoreTotalItem = result.GroupBy(m => new { m.Description }).Select(g => new DescriptionAmountModel { Amount = g.Sum(a => a.Amount).Value, Description = g.Key.Description }).OrderByDescending(x => x.Amount); 
Смежные вопросы