如何获取嵌套在IGrouping集合中的类的属性

时间:2019-06-27 07:39:13

标签: c# asp.net-core reflection

我创建了一个通用的排序方法。我选择了列表的类型,然后从视图中查找了与排序顺序相同的道具名称。现在,我有了一个REVOKE ALL ON DATABASE no_access_db FROM ROLE role; REVOKE ALL ON TABLE no_access_db.tb FROM ROLE role; 集合的案例-例如IGrouping,但我不知道如何按嵌套在List<IGrouping<int, ViewModel>>

中的ViewModel的道具进行排序
IGrouping

EDIT2:

我添加了:

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

但是我遇到错误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);
}

ViewComponent

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

排序类别

    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

1 个答案:

答案 0 :(得分:1)

我找不到在小组中工作的方法。解决我问题的唯一方法是-从小组中取出集合,然后下订单,然后重新分组。

另外,按id分组是错误的主意,正确的结果是当我们将相同的道具分组后,其顺序是什么

public static List<IGrouping<object, T>> SortOrder<T>(List<IGrouping<object, T>> list, string sortOrder) where T : new()
{
    Type listType = AssemblyHelper.GetCollectionType(list);
    if (listType.Name.Contains("IGrouping"))
    {
        var t = list.SelectMany(x => x);
        Type tType = AssemblyHelper.GetCollectionType(t);
        foreach (var prop in tType.GetProperties())
        {
            if (prop.Name.ToLower() == Value)
            {
                if (sortOrder.Contains("_"))
                {
                    sortOrder = Value + sortOrder.Substring(sortOrder.IndexOf("_"));
                }
                else
                {
                    sortOrder = Value;
                }
            }
            if (prop.Name.ToLower() == sortOrder)
            {
                return t.OrderBy(x => prop.GetValue(x, null)).GroupBy(x => prop.GetValue(x, null)).ToList();
            }
            else if (prop.Name.ToLower() + Sort.Desc == sortOrder)
            {
                return t.OrderByDescending(x => prop.GetValue(x, null)).GroupBy(x => prop.GetValue(x, null)).ToList();
            }
        }
    }
    return default(List<IGrouping<object, T>>);
}