Как отформатировать литералы даты в динамическом linq? - PullRequest
4 голосов
/ 18 февраля 2010

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

        StringBuilder whereClause = new StringBuilder();

        if (startDate.HasValue || endDate.HasValue)
        {
            DateTime searchStartDate = startDate.HasValue ? startDate.Value : DateTime.MinValue;
            DateTime searchEndDate = endDate.HasValue ? endDate.Value : DateTime.MaxValue;

            whereClause.AppendFormat("Date >= {0} && Date <= {1}",
                searchStartDate.Date.ToUniversalTime(),
                searchEndDate.Date.ToUniversalTime());
        }

        if (whereClause.Length > 0)
        {
            return (from p in this.repository.GetQueryable<Party>() select p)
                .Where(whereClause.ToString())
                .ToList();
        }

Запрос падает, потому что выполняется сравнение между полем DateTime и полем Int32, то есть запрос интерпретировал мои литералы даты как целые числа.

Как мне форматировать даты?

Ответы [ 3 ]

8 голосов
/ 18 февраля 2010

Вместо этого используйте

.Where("Date >= @0 && Date <= @1",
                searchStartDate.Date.ToUniversalTime(),
                searchEndDate.Date.ToUniversalTime())

.

В ответ на комментарий Вала:

ОК, тогда вы можете сделать:

whereClause.AppendFormat("Date.ToString() >= \"{0}\" && Date.ToString() <= \"{1}\"",
                searchStartDate.Date.ToUniversalTime(),
                searchEndDate.Date.ToUniversalTime());

Вы должны преобразовать дату в запросе в строку, а затем сравнить ее со строковым литералом в кавычках.Без кавычек парсер интерпретирует числа, вставленные в предложение where, как целые числа - что должно объяснить ошибку, которую вы изначально получили.

1 голос
/ 22 октября 2015

Строка Dynamic LINQ должна выглядеть примерно так:

"Date >= DateTime(2015, 10, 21)"

Это упоминается в документации по проекту DynamicQuery в загрузке, упомянутой по адресу http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library.

Обратите вниманиене new до конструктора DateTime.

Я попробовал это, и это работает.Я использую Telerik RadGrid для ASP.NET AJAX.Сетка строит строку фильтра, и мне нужно было добавить фильтр в мой запрос, чтобы фильтр выполнялся в базе данных, используя LINQ to Entities.Проблема в том, что сгенерированный фильтр нужно немного изменить, чтобы он работал с LINQ to Entities, а не с LINQ to Objects.Он делал DateTime.Parse(), который не поддерживается в LINQ to Entities.

1 голос
/ 18 февраля 2010

Почему вы анализируете строки в выражении LINQ? Весь смысл LINQ состоит в том, чтобы этого избежать.

var q =  from p in this.repository.GetQueryable<Party>() select p;

if (startDate.HasValue || endDate.HasValue) 
{ 
  var searchStartDate = startDate.HasValue ? startDate.Value : DateTime.MinValue; 
  var searchEndDate = endDate.HasValue ? endDate.Value : DateTime.MaxValue; 
  return 
         q.Where (p=> p.Date >= searchStartDate.ToUniversalTime() 
                   && p.Date <= searchEndDate.ToUniversalTime()).ToList();
} 
return q.ToList();

UPDATE: В ответ на комментарии: я создаю это во время выполнения. Вопрос не во время выполнения против времени компиляции; это "в строках" против "в коде". StringBuilder позволяет добавлять текст; LINQ позволяет связать Lamdbas. Все работает одинаково - за исключением того, что ваш код является типобезопасным, а синтаксис проверяется с помощью лямбды.

Чтобы еще больше продемонстрировать эту концепцию, следующий код компилируется и работает нормально и позволяет вам изменять предложение Where на основе значений oddsOnly и lowerLimit.

int[] nums = {1,2,3,4,5,6,7,8,9,10};

bool oddsOnly = true; 
bool lowerLimit = 5;

var q = from i in nums select i;

if (oddsOnly)
    q = q.Where( n=> n%2 == 1);

if (lowerLimit != 0)
    q = q.Where( n=> n >= lowerLimit);

foreach(var i in q)
    Console.WriteLine(i);

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

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