Я создал универсальный метод для сортировки.Я взял тип списка, а затем поиск имени проп, который равен виду сортировки в поле зрения.Теперь у меня есть случай с коллекцией 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