Использование Linq для ObjectDataSource: Как преобразовать дату и время, используя ToShortTimeString? - PullRequest
1 голос
/ 16 января 2009

Я обращаюсь к бизнес-классу с использованием ObjectDataSource и пытаюсь произвести вывод, который имеет смысл для пользователя. Возвращаемые значения описывают класс (как в классе и обучении, а не как программное обеспечение). Я хотел бы показать время урока в следующем диапазоне: «9:00 - 10:00».

Это запрос Linq, который я использую для извлечения данных:

return classQuery.Select(p => new SelectClassData
                              {
                                   ClassID = p.ClassID,
                                   Title = p.Title,
                                   StartDate = p.StartDate.ToShortDateString(),
                                   EndDate = p.EndDate.ToShortDateString(),
                                   TimeOfClass =
                                   p.StartDate.ToShortTimeString() + " - " +
                                                       p.EndDate.ToShortTimeString()
                               }).ToList();

Как видите, я кодирую время начала и окончания в начальной и конечной датах, даже если они потенциально могут быть в разные даты.

Когда я выполняю этот код, я получаю:

"Не удалось перевести выражение 'p.EndDate.ToShortTimeString ()' в SQL и не удалось обработать его как локальное выражение."

Я знаю, что проецирую результаты, но, будучи новичком в Linq, я предполагал, что C # вызов ToShortTimeString произошел после проекции. Может кто-нибудь помочь мне понять, как получить строку, которую я ищу?

Ответы [ 2 ]

4 голосов
/ 16 января 2009

Причина в том, что запрос используется в LINQ to SQL. LINQ to SQL обрабатывает запросы как деревья выражений. У него есть определения, определенные для некоторых методов (например, Contains), но поскольку он на самом деле не выполняет их, он не может работать с произвольными методами. Он анализирует запрос и отправляет его на сервер SQL. Эквивалент запроса будет выполнен как оператор SQL на сервере базы данных, и результат вернется. Проблема в том, что ToShortTimeString() не имеет эквивалентного перевода SQL в LINQ to SQL. Прием, используемый здесь, заключается в получении данных с сервера SQL и вызове метода на стороне клиента (AsEnumerable сделает это).

return classQuery.Select(p => new { p.ClassID, p.Title, p.StartDate, p.EndDate })
   .AsEnumerable()
   .Select(p => new SelectClassData { 
       ClassID = p.ClassID, 
       Title = p.Title, 
       StartDate = p.StartDate.ToShortDateString(), 
       EndDate = p.EndDate.ToShortDateString(), 
       TimeOfClass = p.StartDate.ToShortTimeString() + " - " + p.EndDate.ToShortTimeString() })
   .ToList();
0 голосов
/ 16 января 2009

Мне очень нравится ответ Мердада. Это не только решает проблему, но и учит меня кое-чему о Linq. Спасибо!

Я продолжал разбираться с проблемой, хотя и придумал другой подход, который я опишу здесь на случай, если кто-то, спотыкающийся в этом вопросе, захочет рассмотреть. Мой код Linq to SQL теперь выглядит так:

return classQuery.Select(p => new SelectClassData
                              {
                                   ClassID = p.ClassID,
                                   Title = p.Title,
                                   sDate = p.StartDate,
                                   eDate = p.EndDate
                              }).ToList();

Обратите внимание, что sDate и eDate теперь являются объектами DateTime, а не строками. В объекте «SelectClassData» я просто изменил объявление, чтобы доступ к переменным StartDate, EndDate и TimeOfClass проходил через свойство getter:

public class SelectClassData
{
    public int ClassID { get; set; }
    public string Title { get; set; }
    public DateTime sDate { get; set; }
    public DateTime eDate { get; set; }
    public string StartDate { get { return GetSDate(); } }
    public string EndDate { get { return GetEDate(); } }
    public string TimeOfClass { get { return GetTimeOfClass(); } }

    protected string GetSDate()
    {
        return sDate.ToShortDateString();
    }

    protected string GetEDate()
    {
        return eDate.ToShortDateString();
    }

    protected string GetTimeOfClass()
    {
        return sDate.ToShortTimeString() + " - " + eDate.ToShortTimeString();
    }
}

То есть я устанавливаю sDate и eDate через LinqToSql, но выполняю преобразования "ToShortTimeString" и "ToShortDateString" после извлечения Linq, реализуя его в целевом классе данных.

...