Umesh AP Ответов: 1

LINQ where предложение для поля nullable datetime


Я занимаюсь разработкой MVC-приложения с Поиск, разбиение на страницы. У меня есть элемент управления uploaddate calendar для фильтрации со многими другими полями. Это может быть null или может содержать дату.

Как написать предложение LINQ where, которое извлекает записи, UploadDate которых (имя столбца) равно заданному UploadDate в форме.

public ActionResult MultipleSearch(string searchByUserName, string searchByReaderName, int? searchByReaderType, string searchByUploadDate, int? page)
        {
            return View(db.TestUploadData2.Where(a =>
                (String.IsNullOrEmpty(searchByUserName) || a.UserName.StartsWith(searchByUserName)) &&
                (String.IsNullOrEmpty(searchByReaderName) || a.ReaderName.StartsWith(searchByReaderName)) &&
                (String.IsNullOrEmpty(searchByUploadDate) || a.UploadDate.ToShortDateString() == searchByUploadDate)                 
                ).Where(var => var.ReaderTypeId == searchByReaderType || var.ReaderTypeId > 0).ToList().ToPagedList(page ?? 1, 100));
        }



При таком подходе получение ошибки как "
LINQ to Entities does not recognize the method 'System.String ToShortDateString()' method, and this method cannot be translated into a store expression.

"

Заменяющий
(String.IsNullOrEmpty(searchByUploadDate) || a.UploadDate.ToShortDateString() == searchByUploadDate )

С
(String.IsNullOrEmpty(searchByUploadDate) || DateTime.Compare(a.UploadDate, Convert.ToDateTime(searchByUploadDate)) == 0)


дает ошибку как
LINQ to Entities does not recognize the method 'System.DateTime ToDateTime(System.String)' method, and this method cannot be translated into a store expression.




Пожалуйста, дайте предложение.

Что я уже пробовал:

Много гуглил по этому вопросу, но не смог найти подходящего решения. Обратите внимание, что параметр searchByUploadDate может быть нулевым или содержать дату...

1 Ответов

Рейтинг:
5

Richard Deeming

Преобразуйте значение даты в C#, прежде чем передавать его в запрос:

DateTime uploadDate;
bool haveUploadDate = !string.IsNullOrEmpty(searchByUploadDate) && DateTime.TryParse(searchByUploadDate, out uploadDate);

IQueryable<YourEntity> result = db.TestUploadData2;
if (haveUploadDate)
{
    result = result.Where(a => a.UploadDate == uploadDate);
}
if (!string.IsNullOrEmpty(searchByUserName))
{
    result = result.Where(a => a.UerName.StartsWith(searchByUserName));
}
if (!string.IsNullOrEmpty(searchByReaderName))
{
    result = result.Where(a => a.ReaderName.StartsWith(searchByReaderName));
}
if (searchByReaderType != null)
{
    result = result.Where(a => a.ReaderTypeId == searchByReaderType.Value);
}

return View(result.ToPagedList(page ?? 1, 100));


Umesh AP

@Richard - большое вам спасибо за ответ.
Вышеописанное решение работает только в том случае, если UploadDate (который является столбцом DateTime) имеет время, равное 00:00:00.000.
Как изменить вышеизложенное, чтобы оно работало только на части даты, игнорируя часть времени.

Richard Deeming

Попробуйте либо:
result = result.Where(a => DbFunctions.TruncateTime(a.UploadDate) == uploadDate);

или:

DateTime uploadDateMax = uploadDate.AddDays(1);
result = result.Where(a => a.UploadDate >= uploadDate && a.UploadDate < uploadDateMax);



Второй вариант, вероятно, лучше, так как SQL сможет использовать индекс столбца для удовлетворения запроса.

Umesh AP

@Richard Deeming-большое вам спасибо за ценную поддержку....