Заказ с использованием Iqueryable для данных - PullRequest
0 голосов
/ 26 июня 2018

У меня есть следующая функция, которая подготавливает данные для сетки данных jquery. Теперь я сталкиваюсь со следующей ошибкой для типа данных, отличного от строки

Невозможно привести тип «System.DateTime» к типу «System.Object». LINQ to Entities поддерживает только приведение типов примитивов и перечислений EDM.

Код:

public GeneralResponse<IEnumerable<Holiday>> GetHolidays(string filter, 
                int initialPage, 
                int pageSize, 
                out int totalRecords, 
                out int recordFilterd,
                int sortColumn, 
                string sortDirection)
            {
                var response = new GeneralResponse<IEnumerable<Holiday>>();
                totalRecords = 0;
                recordFilterd = 0;
                filter = filter.Trim().ToLower();
                try
                {
                    Expression<Func<Holiday, dynamic>> expr;
                    switch (sortColumn)
                    {
                        case 0:
                            expr = p => p.HolidayDate;
                            break;
                        case 1:
                            expr = p => p.Name;
                            break;
                        case 2:
                            expr = p => p.ExchangeMarket.Name;
                            break;
                        default:
                            expr = p => p.CreatedOn;
                            break;
                    }
                    var data = holidayRepository.Query(true);
                  //var data = holidayRepository.GetAll(true).AsQueryable(); previous working one



                    totalRecords = data.Count();
                    //filter 
                    if (!string.IsNullOrWhiteSpace(filter))
                    {
                        data = data.Where(x => x.Name.ToLower().Contains(filter));
                        //todo : Add date search as well 
                    }
                    recordFilterd = data.Count();
                    //sort 
                    data = sortDirection == "asc" ? data.OrderBy(expr) : data.OrderByDescending(expr);

                    data = data
                        .Skip(initialPage * pageSize)
                        .Take(pageSize);

                    var result = data.ToList();
                    response.Data = result;

                }
                catch (Exception e)
                {
                    response.Error = true;
                    response.Exception = e;
                }
                return response;
            }

// This method is under generic repository 
     public IQueryable<T> Query()
            {
               return Query(false);
            }

ранее я использовал IEnumerable, который сначала загружал все данные в списке, а затем выполнял фильтр, который работал нормально (но не правильно или не рекомендуется)

Теперь я застрял с частью фильтра. Как я могу исправить эту ошибку, чтобы иметь порядок по всем типам столбцов свойств?

Я провел много исследований, но не смог найти никакого решения.

1 Ответ

0 голосов
/ 26 июня 2018

dynamic или object нельзя использовать как TKey универсальный аргумент EF Queryable.OrderBy (фактически в любом выражении метода Queryable) - это должен быть фактический тип ключ. Это, в свою очередь, означает, что вы не можете использовать общую переменную Expression<Func<...>> для хранения выражения keySelector.

Решением является использование условного .OrderBy[Descending] внутри вашего блока switch / case.

Чтобы упростить обработку восходящего / нисходящего параметра (и избежать дублирования выражений), начните с создания простого пользовательского метода расширения, такого как:

namespace System.Linq
{
    public static class QueryableExtensions
    {
        public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, bool ascending)
        {
            return ascending ? source.OrderBy(keySelector) : source.OrderByDescending(keySelector);
        }
    }
}

Затем переместите блок switch / case после

recordFilterd = data.Count();

и используйте вышеуказанный вспомогательный метод внутри:

bool ascending = sortDirection == "asc";
switch (sortColumn)
{
    case 0:
        data = data.OrderBy(p => p.HolidayDate, ascending);
        break;
    case 1:
        data = data.OrderBy(p => p.Name, ascending);
        break;
    case 2:
        data = data.OrderBy(p => p.ExchangeMarket.Name, ascending);
        break;
    default:
        data = data.OrderBy(p => p.CreatedOn, ascending);
        break;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...