/// <summary> /// Sorts an IQueryable by a value on a navigation property of the main collection (e.g. sort Album by Album.Artist.Name). /// </summary> /// <typeparam name="T">The type of the base collection (e.g. Album).</typeparam> /// <param name="source">The base collection to sort (e.g. IQueryable<Album>).</param> /// <param name="sort">The sort to be applied (e.g. Field = 'Name', Direction = 'Ascending').</param> /// <param name="navigationPropertyName">The navigation property to sort on (e.g. 'Artist').</param> /// <returns>the IOrderedQueryable, sorted by the navigation property specified.</returns> public static IOrderedQueryable <T> NavigationSort <T>(this IQueryable <T> source, ISort sort, string navigationPropertyName) { var dest = source as IOrderedQueryable <T>; var sortExpression = SortExpressionBuilder.GetSortExpression(ref dest, sort, navigationPropertyName); if (sortExpression != null) { dest = (sort.Direction == SortDirection.Ascending) ? source.OrderBy(sortExpression) : source.OrderByDescending(sortExpression); } return(dest); }
public override bool TryHandleEnter( QueryableSortContext context, ISortField field, ObjectFieldNode node, [NotNullWhen(true)] out ISyntaxVisitorAction?action) { if (node.Value.IsNull()) { context.ReportError( ErrorHelper.CreateNonNullError(field, node.Value, context)); action = SyntaxVisitor.Skip; return(true); } if (field.RuntimeType is null) { action = null; return(false); } if (!(context.GetInstance() is QueryableFieldSelector lastFieldSelector)) { throw ThrowHelper.Sorting_InvalidState_ParentIsNoFieldSelector(field); } Expression lastSelector = lastFieldSelector.Selector; Expression nextSelector = field.Member switch { PropertyInfo i => Expression.Property(lastSelector, i), MethodInfo i => Expression.Call(lastSelector, i), { } i => throw ThrowHelper.QueryableSorting_MemberInvalid(i, field), null => throw ThrowHelper.QueryableSorting_NoMemberDeclared(field), }; if (context.InMemory) { nextSelector = SortExpressionBuilder.IfNullThenDefault( lastSelector, nextSelector, Expression.Default(field.RuntimeType.Source)); } context.PushInstance(lastFieldSelector.WithSelector(nextSelector)); context.RuntimeTypes.Push(field.RuntimeType); action = SyntaxVisitor.Continue; return(true); }
//I have two forms of predicate because I need to pass in null if predicate is null. Otherwise I need to convert it into delegate and pass it into // data view's constructor. That logic for checking null can't be embedded in the base constructor call. /// <summary> /// /// </summary> /// <param name="table">Table from which to create the view</param> /// <param name="predicate_func">User-provided filter-predicate as a Func<DataRow>, bool>"/></param> /// <param name="predicate_system">User-provided predicate but in the form of System.Predicate<DataRow> /// Predicates are being replicated in different forms so that nulls can be passed in. /// For e.g. when user provides null predicate, base.Predicate should be set to null. I cant do that in the constructor initialization /// if I will have to create System.Predicate delegate from Func. /// </param> /// <param name="comparison">The comparer function of DataRow to be used for sorting. </param> /// <param name="comparerKeyRow">A comparer function that compares a Key value to DataRow.</param> /// <param name="isDescending">Whether sorting is ascending or descending.</param> /// <param name="rowState">Row state filter. For the purpose of LinkDataView it should always be CurrentRows.</param> internal LinqDataView( DataTable table, Func<DataRow, bool> predicate_func, Predicate<DataRow> predicate_system, Comparison<DataRow> comparison, Func<object, DataRow, int> comparerKeyRow, SortExpressionBuilder<DataRow> sortExpressionBuilder) //Parent constructor : base(table, predicate_system, comparison, DataViewRowState.CurrentRows) { this.sortExpressionBuilder = (sortExpressionBuilder == null) ? this.sortExpressionBuilder : sortExpressionBuilder; this.comparerKeyRow = comparerKeyRow; }
/// <summary> /// Sorts an IQueryable by one or more fields. /// </summary> /// <typeparam name="T">The collection type.</typeparam> /// <param name="source">The collection to be sorted.</param> /// <param name="sorts">One or more ISort objects by which to sort the collection..</param> /// <returns>the IOrderedQueryable, sorted as specified by the ISort object(s).</returns> public static IOrderedQueryable <T> Sort <T>(this IQueryable <T> source, IEnumerable <ISort> sorts) { var dest = source as IOrderedQueryable <T>; if (sorts == null || !sorts.Any()) { return(dest); } var expression = SortExpressionBuilder.GetSortExpression(ref dest, sorts); if (expression != null) { dest = dest.Provider.CreateQuery <T>(expression) as IOrderedQueryable <T>; } return(dest); }
/// <summary> /// Sorts an IQueryable by one or more fields. /// </summary> /// <typeparam name="T">The collection type.</typeparam> /// <param name="source">The collection to be sorted.</param> /// <param name="sorts">One or more ISort objects by which to sort the collection..</param> /// <returns>the IOrderedQueryable, sorted as specified by the ISort object(s).</returns> public static IOrderedQueryable <T> Sort <T>(this IQueryable <T> source, IEnumerable <ISort> sorts) { var dest = source as IOrderedQueryable <T>; if (dest == null) { // if we couldn't cast to IOrderedQueryable, // apply a dummy sort against a constant value // to get an IOrderedQueryable dest = source.OrderBy(x => 0); } if (sorts == null || !sorts.Any()) { return(dest); } SortExpressionBuilder.ApplySorts(ref dest, sorts); return(dest); }
/// <summary> /// Constructs a LinkDataView and its parent DataView. /// Does not create index on the DataView since filter and sort expressions are not yet provided. /// </summary> /// <param name="table">The input table from which LinkDataView is to be created.</param> internal LinqDataView(DataTable table, SortExpressionBuilder<DataRow> sortExpressionBuilder) : base(table) { Debug.Assert(table != null, "null DataTable"); this.sortExpressionBuilder = sortExpressionBuilder ?? new SortExpressionBuilder<DataRow>(); }
public void Setup() { _builder = new SortExpressionBuilder<TestSource>(); }