2015-06-20 2 views
0

Я хочу получить счетчик для статуса в течение следующих 10 дней в одном удалении базы данных, используя linq в C#. например:Получить отчеты за следующие 10 дней в одной базе данных

Table : Task 
Coulmun: Id  Status  DueDate 
Value  1  New   Jan 1 2013 
Value  2  New   Jan 3 2013 
Value  3  In Progress Jan 1 2014 
Value  4  Completed Jun 21 2016 

Теперь я хочу, чтобы принести отчет в течение следующих 10 дней с сегодняшнего дня с указанием: Нет записи, которые находятся в каждом состоянии. Записи, отсчитанные до сегодняшнего дня, должны быть частью сегодняшней даты и с завтрашней даты, когда он должен рассчитывать на этот конкретный день.

Как я могу достичь этого в одном попадании базы данных. Я не хочу снова запрашивать DB снова n снова 10 раз.

Ожидаемый результат:

Date Jun 20 Jun 21 Jun22 Jun 23 Jun24 Jun 25...... 
New 2  0  0  0  0  0 
InPrg 1  0  0  0  0  0 
Complt 0  1  0  0  0  0 

Решение Пробовал:

SQL запросов:

SELECT count (TaskId) , StatusCode, DueDate from Task 
where dateadd(day, datediff(day, 0, DueDate), 0) BETWEEN CAST('2013/06/08' as DATE) and cast('2013/06/18' as DATE) 
--where CONVERT(DATETIME, DueDate) >CONVERT(DATETIME, '2013/06/08') and CONVERT(DATETIME, DueDate) < CONVERT(DATETIME, '2013/06/18') 
GROUP by StatusCode, DueDate 
order by 1 desc 

Result : 
(No column name) StatusCode DueDate 
1 IP 2013-06-08 08:13:36.080 
1 IP 2013-06-08 09:49:04.263 
1 IP 2013-06-08 10:03:26.550 
1 NW 2013-06-08 10:14:11.247 
1 IP 2013-06-08 10:33:45.760 
1 IP 2013-06-08 20:44:27.427 
1 NW 2013-06-09 01:13:54.150 

Linq Пробовал:

DateTime startdate; 
      DateTime.TryParse("2013/06/08", out startdate); 
      DateTime enddate; 
      DateTime.TryParse("2013/06/18", out enddate); 

var query = repository.Data 
          .Where(x => x.StatusCode != null 
           && EntityFunctions.TruncateTime(x.DueDate) < EntityFunctions.TruncateTime(startdate)) 
          .GroupBy(p => new 
          { 
           p.StatusCode 

          }) 
          .Select(g => new 
          { 
           g.Key.StatusCode, 

           AvailableCpunt = g.Count() 
          }).ToList(); 


       var result1 = repository.Data 
          .Where(x => x.StatusCode != null 
           && EntityFunctions.TruncateTime(x.DueDate) > EntityFunctions.TruncateTime(startdate) 
           && EntityFunctions.TruncateTime(x.DueDate) < EntityFunctions.TruncateTime(enddate)) 
          .GroupBy(p => new 
          { 
           p.StatusCode, 
           p.DueDate 

          }) 
          .Select(g => new 
          { 
           StatusCode = g.Key.StatusCode, 
           DueDate = g.Key.DueDate, 
           AvailableCount = g.Count() 
          }).ToList(); 

Но опять-таки сравнить со временем также и курица Результаты не верны. Может ли кто-нибудь помочь?

+1

Добро пожаловать на Stack Overflow. Когда вы отправляете сообщения, пожалуйста, используйте предварительный просмотр, чтобы проверить, что ваш пост доступен для чтения, прежде чем вы опубликуете - перед редактированием таблицы в вашем вопросе были непонятными. –

+1

Теперь, что вы пробовали? И каков тип 'DueDate'? Похоже, вы могли бы просто использовать два запроса: один для «все в прошлом», группировку по статусу и учетные записи, а также «все между сегодняшним и 10-дневным временем», группировку по статусу, дате и учетным записям. Выполнение этого в одном запросе более сложное, но оно должно быть выполнимо, если вы можете в принципе сказать: «Если срок истекает до сегодняшнего дня, притворись, что он сегодня». Это похоже на вопрос SQL на самом деле - в особенности LINQ. –

+0

Я попытался использовать группу в статусе, чтобы получить результат для прошлых дат. Так он работал, и вы по праву отметили, что можем сделать для второй части, группируя статус и дату, но когда я пытаюсь выполнить ее сравнение временная часть также как duedate является столбцом datetime. DueDate - столбец DateTime. Я попытался использовать CONVERT (DATETIME, DueDate), CAST ('2013/06/08' как DATE), dateadd (день, датированный (день, 0, DueDate), 0), но не из них работают, все сравниваются время также и, следовательно, я получаю так много записей. Не могли бы вы предоставить некоторый фрагмент, для sql и linq, если это возможно в 1 запросе –

ответ

0

Вы должны всегда нарушать проблему в простых запросах, чтобы иметь четкую перспективу того, что вы хотите. Здесь вы можете сначала классифицировать каждую запись как day1, day2, ..., day10. Затем подсчитывайте каждую категорию с группировкой по статусу.

Я думаю, что это будет делать то, что вы хотите:

select 
    Status, 
    SUM(Day1) Day1, SUM(Day2) Day2 , SUM(Day3) Day3 , SUM(Day4) Day4 , SUM(Day5) Day5, 
    SUM(Day6) Day6 , SUM(Day7) Day7 , SUM(Day8) Day8 , SUM(Day9) Day9 , SUM(Day10) Day10 
from(
    select 
     Status, 
     case when DueDate <= cast(GETDATE() as date) then 1 else 0 end Day1, 
     case when DueDate = dateadd(day, 1, cast(GETDATE() as date)) then 1 else 0 end Day2, 
     case when DueDate = dateadd(day, 2, cast(GETDATE() as date)) then 1 else 0 end Day3, 
     case when DueDate = dateadd(day, 3, cast(GETDATE() as date)) then 1 else 0 end Day4, 
     case when DueDate = dateadd(day, 4, cast(GETDATE() as date)) then 1 else 0 end Day5, 
     case when DueDate = dateadd(day, 5, cast(GETDATE() as date)) then 1 else 0 end Day6, 
     case when DueDate = dateadd(day, 6, cast(GETDATE() as date)) then 1 else 0 end Day7, 
     case when DueDate = dateadd(day, 7, cast(GETDATE() as date)) then 1 else 0 end Day8, 
     case when DueDate = dateadd(day, 8, cast(GETDATE() as date)) then 1 else 0 end Day9, 
     case when DueDate = dateadd(day, 9, cast(GETDATE() as date)) then 1 else 0 end Day10 
    from @task 
) t 
group by Status 

А вот LINQ эквивалент:

tasks.Select(a => new 
{ 
    Status = a.Status, 
    Day1 = a.DueDate <= DateTime.Today ? 1 : 0, 
    Day2 = a.DueDate == DateTime.Today.AddDays(1) ? 1 : 0, 
    Day3 = a.DueDate == DateTime.Today.AddDays(2) ? 1 : 0, 
    Day4 = a.DueDate == DateTime.Today.AddDays(3) ? 1 : 0, 
    Day5 = a.DueDate == DateTime.Today.AddDays(4) ? 1 : 0, 
    Day6 = a.DueDate == DateTime.Today.AddDays(5) ? 1 : 0, 
    Day7 = a.DueDate == DateTime.Today.AddDays(6) ? 1 : 0, 
    Day8 = a.DueDate == DateTime.Today.AddDays(7) ? 1 : 0, 
    Day9 = a.DueDate == DateTime.Today.AddDays(8) ? 1 : 0, 
    Day10 = a.DueDate == DateTime.Today.AddDays(9) ? 1 : 0, 
}).GroupBy(a => a.Status).Select(a => new 
{ 
    Status = a.Key, 
    Day1 = a.Sum(b => b.Day1), 
    Day2 = a.Sum(b => b.Day2), 
    Day3 = a.Sum(b => b.Day3), 
    Day4 = a.Sum(b => b.Day4), 
    Day5 = a.Sum(b => b.Day5), 
    Day6 = a.Sum(b => b.Day6), 
    Day7 = a.Sum(b => b.Day7), 
    Day8 = a.Sum(b => b.Day8), 
    Day9 = a.Sum(b => b.Day9), 
    Day10 = a.Sum(b => b.Day10) 
}) 
+0

Привет, Спасибо за помощь, получили представление о том, что нужно сделать. Однако получение ошибки, в то время как я на самом деле ударяю db. Ошибка: LINQ to Entities не распознает метод 'System.DateTime AddDays (Double)', и этот метод не может быть переведен в выражение хранилища. Любые причины, по которым я могу сделать его более динамичным, для например, я передаю N (нет) из пользовательского интерфейса для этого количества отчетов дня, если его N = 10, то 10 дней, если его N = 15, тогда 15 дней ??? –

+0

Для ошибки в linq-версии я бы сохранил DateTime.Today.AddDays (i) в некоторых переменных и использовал его в запросе. но ваш следующий вопрос: это можно сделать динамически, но с такой большой проблемой, beacuase вы хотите, чтобы динамические файлы в вашем результате.Я бы рассмотрел максимальное значение для N и написал запрос для вычисления всех столбцов N, но отобразил только запрошенное количество дней! – Hosein

+0

эй, я попробовал это в реальном мире сегодня, вопрос хороший, но очень плохой по производительности. он занимает много времени, как сканирование каждой записи. Это не может быть и оптимальным решением. вместо этого я попробовал с 2-мя запросами, которые были очень хорошими по производительности, но не смогли добиться единого –

 Смежные вопросы

  • Нет связанных вопросов^_^