Возникла проблема с сортировкой в ​​EF Core и свойстве навигации - PullRequest
0 голосов
/ 06 марта 2019

Я работаю с ядром .net и EF core 2.0. У меня есть следующие 3 таблицы

  1. Пользователь
  2. Роль
  3. UserRoles

Теперь я хочу отобразить данные на экране, где у меня есть 2 столбца 1. Имя пользователя 2. Роль

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

   public async Task<PagedResult<User>> GetAll(string filter, int pageIndex, int pageSize, string sortColumn, string sortDirection)
        {
            filter = filter?.Trim().ToLower();
            var data = usersRepository.Query(true).Include(x => x.UserRoles).ThenInclude(x => x.Role).AsQueryable();

            try
            {
                if (!string.IsNullOrWhiteSpace(filter))
                {
                    data = data.Where(x => x.Username.ToLower().Contains(filter));
                }

                //sort 
                var ascending = sortDirection == "asc";
                if (!string.IsNullOrWhiteSpace(sortColumn))
                {
                    switch (sortColumn.Trim().ToLower())
                    {
                        case "username":
                            data = data.OrderBy(p => p.Username, ascending);
                            break;
                        case "isactive":
                            data = data.OrderBy(p => p.IsActive, ascending);
                            break;
                        case "role":
                            data = data.OrderBy(p => p.UserRoles.OrderBy(o => o.Role.Name), ascending);
                            break;
                        default:
                            data = data.OrderBy(p => p.Username, ascending);
                            break;
                    }
                }

                var test = data.ToList();
            }
            catch (Exception e)
            {
                //todo:
            }
            return await data.GetPaged(pageIndex, pageSize);

        }

Где OrderBy - универсальный метод

 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);
        }

Теперь все работает хорошо, за исключением случаев, когда я передаю столбец поиска «роль».

Это дает мне следующую ошибку.

Исключение : Не удалось сравнить два элемента в массиве.

InnerException : Как минимум один объект должен реализовывать IComparable.

Как я могу справиться с этим сценарием, любая помощь приветствуется.

1 Ответ

0 голосов
/ 07 марта 2019

Используйте средний уровень для управления столбцом имени роли. Для этого я создал новый класс с именем "UserList" с необходимыми свойствами в своем ответе.

public async Task<PagedResult<UserList>> GetAll(string filter, int pageIndex, int pageSize, string sortColumn, string sortDirection)
        {
            filter = filter?.Trim().ToLower();
            var data = usersRepository.Query(true)
                .Include(x => x.UserRoles)
                .ThenInclude(x => x.Role)
                .Select(x => new UserList()
                {
                    Username = x.Username,
                    UserId = x.UserId,
                    IsActive = x.IsActive,
                    RoleId = x.UserRoles.FirstOrDefault().RoleId,
                    RoleName = x.UserRoles.FirstOrDefault().Role.Name
                })
                .AsQueryable();

            try
            {
                if (!string.IsNullOrWhiteSpace(filter))
                {
                    data = data.Where(x => x.Username.ToLower().Contains(filter) || x.RoleName.ToLower().Contains(filter));
                }

                //sort 
                var ascending = sortDirection == "asc";
                if (!string.IsNullOrWhiteSpace(sortColumn))
                {
                    switch (sortColumn.Trim().ToLower())
                    {
                        case "username":
                            data = data.OrderBy(p => p.Username, ascending);
                            break;
                        case "isactive":
                            data = data.OrderBy(p => p.IsActive, ascending);
                            break;
                        case "rolename":
                            data = data.OrderBy(p => p.RoleName, ascending);
                            break;
                        default:
                            data = data.OrderBy(p => p.Username, ascending);
                            break;
                    }
                }
            }
            catch (Exception e)
            {
                //todo:
            }

            return await data.GetPaged(pageIndex, pageSize);

    }
...