2015-05-26 2 views
0

У меня есть таблица настройки с двумя столбцами, «Имя» и «Значение»:Использование LINQ для оптимизации времени цикла

Name  | Value 
-----------+------- 
start_time | 9:30 
end_time | 4:30 
length  | 30 

У меня также есть набор результатов, который дает ряд назначений в период времени:

count | time 
------+-------- 
1  | 09:30 
2  | 12:00 
3  | 14:00 
4  | 15:30 

и мне нужно, чтобы показать все временные интервалы между start_time и END_TIME, с их количеством назначений, как это:

(1) 09:30 
    10:30 
    11:00 
    11:30 
(2) 12:00 
    12:30 
    13:00 
    13:30 
(3) 14:00 
    14:30 
    15:00 
(4) 15:30 

Вот что я получил:

// data is the result of WebMatrix.Data.Database.Query 
public void PrepareHTML(dynamic data) 
{ 
    StringBuilder SB = new StringBuilder(""); 
    TimeSpan time = StartTime; // Start/EndTime are `TimeSpan`s defined in another place 

    // loop from StartTime to EndTime in 30 min increments 
    while(time <= EndTime) 
    { 
     String t = String.Format(@"{0:hh\:mm}", time); 

     try 
     { 
      var d = GetThisTime(t,data); 
      SB.AppendFormat("<option value=\"{0}\">({1}) {0}</option>", t, d["count"]); // error is here: Cannot apply indexing with [] to an expression of type 'object' 
     } 
     catch 
     { 
      SB.AppendFormat("<option value=\"{0}\">{0}</option>", t); 
     } 

     time = time.Add(Length); 
    } 
    H = SB.ToString(); 
} 
public IEnumerable<dynamic> GetThisTime(String time, IEnumerable<dynamic> data) 
{ 
    return from a in data 
      where time.CompareTo(new TimeSpan(a.time)) == 0 
      select a; 
} 

Update: «ошибка» Я положил в комментариях не было видно, так что я буду дублировать здесь: я получаю сообщение об ошибке при

SB.AppendFormat("<option value=\"{0}\">({1}) {0}</option>", t, d["count"]); 

Погрешность является:

Невозможно применить индексирование с [] к выражению 'объекта' типа

Поскольку кажется непонятным: я не хочу подсчет IEnumerable, мне нужен столбец count набора данных. См. Вторую таблицу выше.

+1

Это работает? Если нет, что он производит? Что бы вам хотелось? –

+0

'GetThisTime' возвращает' IEnumerable', поэтому его коллекция, если вы хотите использовать _Count_, вам нужно использовать linq [_Count_] (https://msdn.microsoft.com/en-us/library/bb535181 (v = vs.110) .aspx) метод, подобный 'd.Count()' – Grundy

+0

@ LasseV.Karlsen в комментарии к коду: '// ошибка здесь: Невозможно применить индексирование с [] к выражению типа 'object'' – Grundy

ответ

1

GetThisTimeIEnumerable<dynamic>, так что это коллекция, но вы пытаетесь использовать ее как объект. В любом случае вам нужно сначала получить объект, например, с First или FirstOrDefault, и только затем попробуйте получить значение свойства.

Вы можете немного изменить GetThisTime процедурный, так что вы не использовать результат, за исключением в одном месте вы можете рассчитывать просто вернуть то, что вам нужно, как этот

public dynamic GetThisTime(String time, IEnumerable<dynamic> data) 
{ 
    return (from a in data 
      where time.CompareTo(new TimeSpan(a.time)) == 0 
      select a["count"]).FirstOrDefault(); 
} 

и использовать его как

SB.AppendFormat("<option value=\"{0}\">({1}) {0}</option>", t, GetThisTime(t,data)); 

ПРИМЕЧАНИЕ: Ваше выражение кажется неправильным: вы пытаетесь сравнить строку с TimeSpan

ОБНОВЛЕНИЕ: Я думаю, вам нужно немного изменить свою логику, как

public void PrepareHTML(dynamic data) 
{ 
    StringBuilder SB = new StringBuilder(""); 
    TimeSpan time = StartTime; // Start/EndTime are `TimeSpan`s defined in another place 

    // loop from StartTime to EndTime in 30 min increments 
    while(time <= EndTime) 
    { 
     String t = String.Format(@"{0:hh\:mm}", time); 
     var d = GetThisTime(t,data); // Send the String instead of TimeSpan 
     if(d != null){ 
      SB.AppendFormat("<option value=\"{0}\">({1}) {0}</option>", t, d); // error is here: Cannot apply indexing with [] to an expression of type 'object' 
     } 
     else 
     { 
      SB.AppendFormat("<option value=\"{0}\">{0}</option>", t); 
     } 

     time = time.Add(Length); 
    } 
    H = SB.ToString(); 
} 

public object GetThisTime(String time, IEnumerable<dynamic> data) 
{ 
    return (from a in data 
      where time == a.time 
      select a["count"]).FirstOrDefault(); 
} 
+0

Это исправляет ошибку, но я получаю список всех времен, подобных этому '() ##: ##'. Значение количества назначений пуст для каждого времени, даже тех, у кого есть встречи. Похоже, что это обходит попытку catch и получает пустой результат, несмотря ни на что, в то время как он не должен даже помещать скобки, если в это время нет назначений. –

+0

@TravisHeeter, вы видите _note_ в ответ? – Grundy

+0

@TravisHeeter, у вас неправильная логика в '' PrepareHTML'', почему вы ожидаете, что исключения заставили простую проверку, что она сначала начинается с интервалом? – Grundy

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