private IQueryable <dynamic> Sort(IQueryable <dynamic> data, SortInfo sortInfo)
 {
     if (!String.IsNullOrEmpty(sortInfo.SortColumn) || ((DefaultSort != null) && !String.IsNullOrEmpty(DefaultSort.SortColumn)))
     {
         return(Sort(data, _elementType, sortInfo));
     }
     return(data);
 }
Esempio n. 2
0
        public IList <GenericWebGridRow> GetRows(SortInfo sortInfo, int pageIndex)
        {
            IEnumerable <dynamic> rowData = _values;

            if (_canSort)
            {
                rowData = Sort(_values.AsQueryable(), sortInfo);
            }

            rowData = Page(rowData, pageIndex);

            try {
                // Force compile the underlying IQueryable
                rowData = rowData.ToList();
            }
            catch (ArgumentException) {
                // The OrderBy method uses a generic comparer which fails when the collection contains 2 or more
                // items that cannot be compared (e.g. DBNulls, mixed types such as strings and ints et al) with the exception
                // System.ArgumentException: At least one object must implement IComparable.
                // Silently fail if this exception occurs and declare that the two items are equivalent
                rowData = Page(_values.AsQueryable(), pageIndex);
            }
            return(rowData.Select((value, index) => new GenericWebGridRow(_grid, value: value, rowIndex: index)).ToList());
        }
 public IList <GenericWebGridRow> GetRows(SortInfo sortInfo, int pageIndex)
 {
     // Data is already sorted and paged. Ignore parameters.
     return(_rows);
 }
Esempio n. 4
0
        private IQueryable <dynamic> Sort(IQueryable <dynamic> data, Type elementType, SortInfo sort)
        {
            Debug.Assert(data != null);

            if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(elementType))
            {
                // IDynamicMetaObjectProvider properties are only available through a runtime binder, so we
                // must build a custom LINQ expression for getting the dynamic property value.
                // Lambda: o => o.Property (where Property is obtained by runtime binder)
                // NOTE: lambda must not use internals otherwise this will fail in partial trust when Helpers assembly is in GAC
                var binder = Binder.GetMember(
                    CSharpBinderFlags.None,
                    sort.SortColumn,
                    typeof(WebGrid),
                    new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }
                    );
                var param  = Expression.Parameter(typeof(IDynamicMetaObjectProvider), "o");
                var getter = Expression.Dynamic(binder, typeof(object), param);
                return(SortGenericExpression <IDynamicMetaObjectProvider, object>(
                           data,
                           getter,
                           param,
                           sort.SortDirection
                           ));
            }

            Expression          sorterFunctionBody;
            ParameterExpression sorterFunctionParameter;

            Expression sorter;

            if (_grid.CustomSorters.TryGetValue(sort.SortColumn, out sorter))
            {
                var lambda = sorter as LambdaExpression;
                Debug.Assert(lambda != null);

                sorterFunctionBody      = lambda.Body;
                sorterFunctionParameter = lambda.Parameters[0];
            }
            else
            {
                // The IQueryable<dynamic> data source is cast as IQueryable<object> at runtime. We must call
                // SortGenericExpression using reflection so that the LINQ expressions use the actual element type.
                // Lambda: o => o.Property[.NavigationProperty,etc]
                sorterFunctionParameter = Expression.Parameter(elementType, "o");
                Expression member = sorterFunctionParameter;
                var        type   = elementType;
                var        sorts  = sort.SortColumn.Split('.');
                foreach (var name in sorts)
                {
                    PropertyInfo prop = type.GetProperty(name);
                    if (prop == null)
                    {
                        // no-op in case navigation property came from querystring (falls back to default sort)
                        if (
                            (DefaultSort != null) &&
                            !sort.Equals(DefaultSort) &&
                            !String.IsNullOrEmpty(DefaultSort.SortColumn)
                            )
                        {
                            return(Sort(data, elementType, DefaultSort));
                        }
                        return(data);
                    }
                    member = Expression.Property(member, prop);
                    type   = prop.PropertyType;
                }
                sorterFunctionBody = member;
            }

            var actualSortMethod = SortGenericExpressionMethod.MakeGenericMethod(
                elementType,
                sorterFunctionBody.Type
                );

            return((IQueryable <dynamic>)actualSortMethod.Invoke(
                       null,
                       new object[]
            {
                data,
                sorterFunctionBody,
                sorterFunctionParameter,
                sort.SortDirection
            }
                       ));
        }