преобразовать строку в datetime в LinqToEntities (внутри запроса) - PullRequest
2 голосов
/ 31 января 2012

У меня есть дата в формате строки в таблице, и мне нужно сравнить ее с параметром, чтобы получить все строки, которые соответствуют данной дате. как я могу это сделать? Я не могу использовать DateTime.Parse и Convert.ToDateTime. оба они не поддерживаются (я получаю ошибку). Возможно ли это вообще в Linq ИЛИ мне нужно написать хранимую процедуру для этого из-за этого ограничения?

Примечание: я не могу изменить тип данных столбца с varchar на DateTime, потому что этот столбец также содержит другие значения, а не только даты. это общая таблица, и столбец может содержать значения различных типов на основе значений в других столбцах. изменение этого дизайна выходит за рамки этого вопроса.

пример кода («x» - параметр даты, передаваемый в этот метод):

    from t1 in Table1
    where EntityFunctions.DiffDays(DateTime.Parse(t1.Value),x) == 0
    select new {t1.Col1, t1.Col2};

Обновление: если я использую DateTime.Parse, я получаю ошибку "LINQ to Entities не распознает метод метода System.DateTime Parse (System.String) ', и этот метод нельзя преобразовать в выражение хранилища". аналогичная ошибка и для Convert.ToDateTime.

Ответы [ 5 ]

2 голосов
/ 01 февраля 2012

Это работает. Вам нужен метод Extension для того, чтобы сделать анализ dateTime безопасным. После этого вы можете использовать результат этого метода в запросе Linq. Он извлечет все строки из таблицы, поэтому с точки зрения производительности это может быть менее оптимальным (!) Решением. Это отвечает на вопрос, хотя.

    void Main()
    {
         var stringDates = new List<string> { "2011-13-01", "2011-01-12" };

         DateTime paramDate = new DateTime(2011,01,13);

         var q = from stringDate in stringDates
            let realdate = stringDate.SafeParse()
            where realdate == paramDate
            select new { stringDate, realdate };

         q.Dump();
    }


    static class StringDateParseExt
    {
       public static DateTime SafeParse(this string  any)
        {
          DateTime parsedDate;
          DateTime.TryParseExact(any, 
                "yyyy-dd-MM", 
                System.Globalization.CultureInfo.InvariantCulture , 
                System.Globalization.DateTimeStyles.None, 
                out parsedDate);
          return parsedDate;
        }
    }
1 голос
/ 31 января 2012

(репликация моего комментария для вставки примера кода)

Если дата в строковом формате, не могли бы вы применить ToString к вашему DateTime (предположительно x), а затем выполнить сравнение строк?

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

  • Расхождения в формате даты и времени (dd/MM/yyyy против MM/dd/yyyy).
  • Наличие или отсутствие начальных нулей для однозначных дней и месяцев (например, 01/01/2011 против 1/1/2001).
  • Двузначное или четырехзначное представление года (например, 01/01/2011 против 01/01/11).
  • Смещение часового пояса. Например, дата для 2011-01-01 23:30 -01:00 будет фактически 2011-01-02.

Пример кода ниже будет работать, если все ваши даты в американском формате, с двузначными днями и месяцами, четырехзначными годами и без смещения часового пояса.

from t1 in Table1
where t1.Value.StartsWith(x.ToString(@"MM\/dd\/yyyy"))
select new {t1.Col1, t1.Col2};

Редактировать : Альтернативное решение:

Если вы можете определить представление в своей базе данных, вы можете обойти проблему, выборочно приведя ваш VARCHAR к DATETIME. Я предполагаю, что Value - это название вашего столбца даты.

SELECT CONVERT(DATE, Value, 101) AS Value, Col1, Col2
FROM Table1
WHERE ISDATE(Value) = 1

Затем в вашем LINQ выполните простую DateTime проверку на равенство:

from t1 in Table1
where t1.Value == x.Date
select new {t1.Col1, t1.Col2};
0 голосов
/ 13 апреля 2016

Помимо проблем, которые @Douglas указывает на работу со строковыми представлениями, вы можете преобразовать string в DateTime в Linq в Entities , используя SqlFunctions и DbFunctions классы:

DbFunctions.CreateDateTime(SqlFunctions.DatePart("yy", dateString),
                           SqlFunctions.DatePart("mm", dateString),
                           SqlFunctions.DatePart("dd", dateString),
                           SqlFunctions.DatePart("hh", dateString),
                           SqlFunctions.DatePart("mi", dateString),
                           SqlFunctions.DatePart("ss", dateString));
0 голосов
/ 01 февраля 2012

Linq to SQL поддерживает Convert.ToDateTime для перехода от String к DateTime. Я не уверен насчет Entity Framework, если вы действительно используете это вместо этого. Существует также класс SqlMethods с методом DateDiff, который можно использовать для перевода в функцию DateDiff TSQL.

Linq to SQL также позволит вам преобразовывать типы путем приведения. Вы не можете напрямую приводить между String и DateTime, но вы можете обмануть, приведя сначала к Object, а затем к DateTime. Приведение объекта в преобразовании стирается, но преобразование DateTime преобразуется в операцию преобразования TSQL.

0 голосов
/ 31 января 2012

Вы пробовали кастинг?

Expression<Func<string, DateTime>> expr = s => (DateTime)(object)s;

Дальнейший поиск в Интернете показывает, что отсутствие преобразования строки в дату является отсутствующей функцией в EF. Похоже, что поддерживаются некоторые преобразования строк, но нет разбора даты: http://msdn.microsoft.com/en-us/library/dd466166.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...