Как получить свойство класса, вложенного в коллекцию IGrouping - PullRequest
1 голос
/ 27 июня 2019

Я создал универсальный метод для сортировки.Я взял тип списка, а затем поиск имени проп, который равен виду сортировки в поле зрения.Теперь у меня есть случай с коллекцией IGrouping - например, List<IGrouping<int, ViewModel>>, и я не знаю, как сортировать по реквизиту из ViewModel, который вложен в IGrouping

    public static List<IGrouping<int, T>> SortOrder<T>(List<IGrouping<int, T>> list, string sortOrder) where T : new()
    {
        Type listType = AssemblyHelper.GetCollectionType(list);
        if (listType.Name.Contains("IGrouping")) { listType = listType.GenericTypeArguments[1]; }

        foreach (var prop in listType.GetProperties())
        {
            if (prop.Name.ToLower() == sortOrder)
            {
                if (AssemblyHelper.GetCollectionType(list).Name.Contains("IGrouping"))
                {
EDIT 2: var test = list.OrderBy(x => x.Select(y => prop.GetValue(y, null))).ToList();

                    return //How to OrderBy ViewModel prop that is equal to sort order
                }
                else
                {
                    return list.OrderBy(x => prop.GetValue(x, null)).ToList();
                }
            }
        }
        return default(List<IGrouping<int, T>>);
    }

EDIT2:

Я добавил:

var test = list.OrderBy(x => x.Select(y => prop.GetValue(y, null))).Skip((pageId - 1) * pageSize).Take(pageSize).ToList();

но я получаю сообщение об ошибке System.ArgumentException: 'At least one object must implement IComparable.'

Итак, я добавил что-то подобное в ImageObjectModel модель:

public int CompareTo(ImageObjectModel that)
{
    if (this.Name == that.Name) return 0;
    return 1;
}

но я все еще получаю эту ошибку.

РЕДАКТИРОВАТЬ:

Контроллер

public ViewResult List(string sortOrder = "", string filter = "")
{
    List<IGrouping<int, ImageObjectModel>> images = null;
    //the rest of views are using just a list, only for this view purpouse I have to use IGrouping collection
    if (!string.IsNullOrEmpty(filter))
    {
        images = Filter.MultipleWhereClause(repositoryImageObject.Images.ToList(), filter);
    }
    else
    {
        images = repositoryImageObject.Images.ToList();
    }
    //some logic not related
    if (!string.IsNullOrEmpty(sortOrder))
    {
        imvm.Images = Sort.SortOrder(images, sortOrder);
    }
    ImageManagerViewModel imvm = new ImageManagerViewModel(images, pageId, sortOrder, filter, isActive);
}

Вид

@await Component.InvokeAsync("DataFilterSortOrderDropDown", new DataFilter.SortOrderDropDown { Obj = Model.Images, SortOrder = Model.SortOrder })

ViewComponent

    public class DataFilterSortOrderDropDownViewComponent : ViewComponent
    {
        private List<SelectListItem> sortOrderList = new List<SelectListItem>();

        public IViewComponentResult Invoke(DataFilter.SortOrderDropDown vm)
        {
            vm.Error = false;
            if (vm.Obj is ICollection<ProductModel>)
            {
                Type collectionType = AssemblyHelper.GetCollectionType(vm.Obj as ICollection<ProductModel>);
                vm = SortOrder(collectionType, sortOrderList, vm);
            }
            //many else if with `vm.Obj is someViewModel`
            else if (vm.Obj is ICollection<IGrouping<int, ImageObjectModel>>)
            {
                Type collectionType = AssemblyHelper.GetCollectionType(vm.Obj as ICollection<IGrouping<int, ImageObjectModel>>);
                vm = SortOrder(collectionType, sortOrderList, vm);
            }
            else
            {
                vm.Error = true;
                return View(vm);
            }

           vm.List.Insert(0, new SelectListItem { Value = "sort", Text = string.Empty });
            return View(vm);
        }

    private DataFilter.SortOrderDropDown SortOrder(Type collectionType, List<SelectListItem> sortOrderList, DataFilter.SortOrderDropDown vm)
    {
        FieldInfo[] fields = AssemblyHelper.GetFields(typeof(Sort));
        if (collectionType.Name.Contains("IGrouping")) { collectionType = collectionType.GenericTypeArguments[1]; }
        foreach (var prop in collectionType.GetProperties())
        {
            //take field from sort class and find it in collection type if there is then create `SelectListItem` for dropdown
        }
        vm.List = sortOrderList;
        return vm;
    }

Класс сортировки

    public const string Name = "name";
    public const string Price = "price";
    public const string Value = "value";
    public const string CreateDate = "createdate";
    public const string EditDate = "editdate";
    public const string Desc = "_desc";
    //etc

    public static IQueryable<T> SortOrder<T> (IQueryable<T> list, string sortOrder) where T : new()
    {
        Type listType = AssemblyHelper.GetCollectionType(list);
        foreach (var prop in listType.GetProperties())
        {
            if (prop.Name.ToLower() == sortOrder && isPaging)
            {
                return list.OrderBy(x => prop.GetValue(x, null));
            }
            else if (prop.Name.ToLower() + Sort.Desc == sortOrder && isPaging)
            {
                return list.OrderByDescending(x => prop.GetValue(x, null))
            }

        }
        return default(IQueryable<T>);
    }

Я удалил много кода для ясности кода.Идея в том, что если у некоторого класса есть какие-то свойства (имя, цена, дата и т. Д.), Создайте для него выпадающий список и отсортируйте все коллекции.

Моя цель - переписать IQueryable для IGrouping

1 Ответ

1 голос
/ 29 июня 2019

Я не нашел способ работать в группе.единственное решение моей проблемы было - вынуть коллекцию из группы, затем сделать заказ, а затем перегруппировать.

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

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