【问题标题】:MvcContrib Grid Sorting on complex object复杂对象上的 MvcContrib 网格排序
【发布时间】:2011-09-28 16:45:44
【问题描述】:

我正在尝试使用MvcContrib 网格控件。但我似乎无法对包含其他对象的复杂对象进行排序。

我已经在这个问题中设置了类似于 OP 的控制器/类/视图。 Sorting with MVCContrib

我尝试将 SortColumnName 用于我的 childobject.property,但它给了我一个错误,说我的主对象没有这个属性。这是我的代码 sn-p

//POCO类

class Issue {
   public int ID {get; get; }
   .....
   public int priorityId {get; set;}
   public virtual Priority priority {get; set;}
}

//控制器代码

    public ViewResult Index(int? pageNo, GridSortOptions sort)
    {
        var issues = db.issues.Include(i => i.priority);
        ViewBag.sort = sort; 

        if (!string.IsNullOrEmpty(sort.Column))
        {
            issues = issues.OrderBy(sort.Column, sort.Direction);
        }
        return View(issues.ToList().AsPagination(pageNo ?? 1, 10));
    }

//查看Grid的代码

@Html.Grid(Model).Sort(ViewBag.sort as GridSortOptions).Columns(column => {
    column.For(issue => Html.ActionLink(" ", "Edit", new { id = issue.ID, areas = "Issues", controller = "Main"}, new { @id="editBtn"})).Named("Edit");
    column.For(issue => Html.ActionLink(issue.ID.ToString(), "Edit", new {id = issue.ID, areas = "Issues", controller = "Main"})).Named("ID").Sortable(true);
     column.For(issue => issue.priority.codeDesc).Named("Priority").SortColumnName("priority.codeDesc").Sortable(true);
}).Empty("No data found")

当我尝试对优先级字符串进行排序时,它给了我一个错误,说“priority.codeDesc 不是问题的属性”。

TIA

【问题讨论】:

    标签: linq sorting grid sql-order-by mvccontrib


    【解决方案1】:

    这里的问题实际上与网格无关,而是与作为 MvcContrib 排序扩展的一部分提供的 .OrderBy 扩展方法有关。这个扩展相当简单,我只写它来涵盖您想要对对象的直接属性进行排序的简单情况,但是在您的情况下,您尝试对嵌套属性(“priority.codeDesc”)进行排序'不支持 - 你不能在这个扩展中使用点符号。

    您要么需要切换到使用不同的机制来执行实际排序,要么如果这是一次性的情况,那么您可以硬编码此特定列的排序逻辑(不理想,但如果它是a one off 那么它比编写一个新的排序机制更简单),例如:

    if (!string.IsNullOrEmpty(sort.Column))
    {
        if(sort.Column == "priority.codeDesc") 
        {
            issues = issues.OrderBy(x => x.priority.codeDesc);
        } 
        else
        {
            issues = issues.OrderBy(sort.Column, sort.Direction);
        }
    }
    

    【讨论】:

    • 感谢您的回复杰里米。我有一大堆这些嵌套属性,所以在这种情况下可能并不理想。有没有可能很快将其添加到 MvcContrib 代码中?
    • 就我个人而言,我没有任何添加这个的计划——我不再积极地在 mvccontrib 代码库上工作(但如果其他人想贡献这个,那么我很乐意将它合并到)。我实际上建议保持视图模型尽可能平坦,并且为了简单起见,不要依赖视图中的复杂对象图。
    • 您可能会查看 Dynamic.Linq OrderBy。我确定有点晚了=P
    【解决方案2】:

    天哪!点!

    我在同一条船上,但感谢上帝,我找到了我们的开发伙伴 Jarrett Meyer 发布的绝妙解决方案。我在过去大约 3 个小时的谷歌搜索后发现了它,就在我决定使用MvcContrib Grid 来提高我的分页和排序时。

    你可以在这里找到完整的帖子:

    Server-Side Sorting With Dynamic LINQ

    他的代码救了我... :D LINQ's Aggregate 函数的使用太棒了!向他夸奖。

    我不得不稍微更改 Jarretts 的原始代码以适应我的需要。这是我修改后的代码:

    public static IQueryable<T> OrderBy<T>(this IQueryable<T> collection, GridSortOptions sortOptions)
    {
        if (string.IsNullOrEmpty(sortOptions.Column))
        {
            return collection;
        }
    
        Type collectionType = typeof(T);
    
        ParameterExpression parameterExpression = Expression.Parameter(collectionType, "p");
    
        Expression seedExpression = parameterExpression;
    
        Expression aggregateExpression = sortOptions.Column.Split('.').Aggregate(seedExpression, Expression.Property);
    
        MemberExpression memberExpression = aggregateExpression as MemberExpression;
    
        if (memberExpression == null)
        {
            throw new NullReferenceException(string.Format("Unable to cast Member Expression for given path: {0}.", sortOptions.Column));
        }
    
        LambdaExpression orderByExp = Expression.Lambda(memberExpression, parameterExpression);
    
        const string orderBy = "OrderBy";
    
        const string orderByDesc = "OrderByDescending";
    
        Type childPropertyType = ((PropertyInfo)(memberExpression.Member)).PropertyType;
    
        string methodToInvoke = sortOptions.Direction == MvcContrib.Sorting.SortDirection.Ascending ? orderBy : orderByDesc;
    
        var orderByCall = Expression.Call(typeof(Queryable), methodToInvoke, new[] { collectionType, childPropertyType }, collection.Expression, Expression.Quote(orderByExp));
    
        return collection.Provider.CreateQuery<T>(orderByCall);
    }
    

    现在您可以在控制器方法中像这样调用此扩展方法:

    var users = Database.Memberships.OrderBy(sort);
    

    其中sort 是位于MvcContrib.UI.Grid 中的GridSortOptions。

    sort.ColumnName 现在可以包含这样的字符串:

    User.UserName
    User.MyRelatedEntity.RelatedEntityProperty
    User.MyRelatedEntity.RelatedEntityProperty.AndSoON 
    

    请注意,当您创建 Grid 列时,您可以指定

    .SortColumnName("User.UserName")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-22
      • 2016-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多