How to get the query sent to server without skip and take

8 posts, 0 answers
  1. Sodi We
    Sodi We avatar
    160 posts
    Member since:
    Apr 2010

    Posted 21 Feb 2011 Link to this post

    Hello,

    I use the QueryableDomainServiceCollectionView<> in a ViewModel to populate a paged gridview. In the viewmodel I have a basic EntityQuery (eg. context.GetEmployees). Because the gridview is bound to the QueryableDomainServiceCollectionView filtering, sorting and grouping will alter the basic EntityQuery. The datapager will also make sure that a Skip and Take is added to the query sent to the server. So far this is default behaviour.

    Now comes the non-default behaviour. Users should be able to export a gridview to excel. Because they want to see more data than only the first page, I use the basic EntityQuery and execute it. So now users can see the whole data, and not just one page. The problem with this approach is that this doesn't take the filtering, sorting and grouping into account.

    I've noticed the LoadingDataEventArgs has a property Query that holds the resulting query WITH filtering, sorting and grouping, but also with the Skip and Take. Finally my question: Is it possible to get the query without the skip and take, but with filtering, grouping and sorting?

    Thank you and kind regards,
    Sodi We
  2. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 22 Feb 2011 Link to this post

    Hello Sodi We,

    Maybe one of these two could help:

    1. Just before exporting switch the paging off, i.e. set the PageSize to 0. This will remove the paging. After you are done with the export -- set the PageSize back to its original value to enable paging.

    2. This one is harder. In the LoadingData event, get the EntityQuery's Expression (e.Query.Query.Expression) and use an ExpressionVisitor to manually strip the the two method calls -- Skip and Take. Maybe something similar to this:

    /// <summary>
    /// A visitor that Removes Skip and Take expressions. Used to strip the expression
    /// dows so that we can take the total count.
    /// </summary>
    private class PagingRemover : ExpressionVisitor
    {
        public static Expression RemovePaging(Expression source)
        {
            return new PagingRemover().Visit(source);
        }
         
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            if (node.Method.Name == "Skip" || node.Method.Name == "Take")
            {
                return this.Visit(node.Arguments[0]);
            }
     
            return base.VisitMethodCall(node);
        }
    }

    I have not actually tried this, but I guess that it should work.

    I hope this helps.

    Kind regards,
    Ross
    the Telerik team
    Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
  3. DevCraft banner
  4. Giovanni
    Giovanni avatar
    8 posts
    Member since:
    Feb 2011

    Posted 01 Mar 2011 Link to this post

    Hello,
    would you please explain better how to use the pagingremover?
    i'm using wcf ria service with riagridview .
    the user at moment after a filter selection on the grid needs to send all list of entities without the paging to a server procedure, but at moment i'm not able to do it since the domain service retrieve only the pagesize.
    I would like not to populate the grid with all entities (25.000) but rather send the filter selelction to the server.
    is it possible?

    cheers

    Giovanni D'Arienzo
    Nike.com
  5. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 01 Mar 2011 Link to this post

    Hello Giovanni,

    Unfortunately, I really could not understand what exactly are you trying to achieve.

    Could you elaborate in a more structured manner?

    Thanks in advance.

    Kind regards,
    Ross
    the Telerik team
    Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
  6. Sodi We
    Sodi We avatar
    160 posts
    Member since:
    Apr 2010

    Posted 01 Mar 2011 Link to this post

    Giovanni,

    In your querymethod on the server, you can put a ToList() on the result like this:

    public IEnumerable<Employee> GetEmployees()
    {
       var result = ObjectContext.Employees.ToList();
       //do something with this list of ALL employees
    }

    The ToList will make sure all employees are loaded in memory on server. The paging will add some extra filters (skip en take) on the result of this query, so only 1 pagesize amount of data is sent to the client.

    Hope this helps,
    Sodi
  7. Giovanni
    Giovanni avatar
    8 posts
    Member since:
    Feb 2011

    Posted 01 Mar 2011 Link to this post

    i'm sorry but my english is not really good.

    I'm using wcf ria service and radgridview in a silverlight project.
    the grid works together with a pager control so with paging and filtering in place. what i'm trying to achieve is:
    after a filter selection i need to collect all list of entities result and send to a wcfservice cause i need to execute a server procedure.
    Since the ria domaincontext load only the page selected, i don't know how to collect all entities related to the filter selection on the grid.
    i hope is more clear.

  8. Giovanni
    Giovanni avatar
    8 posts
    Member since:
    Feb 2011

    Posted 02 Mar 2011 Link to this post

    private void OnCustomersDataSourceLoadingData(object sender, Telerik.Windows.Controls.DomainServices.LoadingDataEventArgs e)
            {
                this.startTime = DateTime.Now;
                this.debugTextBox.Text = string.Format("--> Sending query to server: {0}\r\n"
                    , e.Query.Query.ToString());
                CurrentQuery = e.Query;
      
            }
    Isaved the current query here

    public
    List<OrderAcknowledgement> ExportOrders { get; set; }
           public void Export()
           {
               PagingRemover.RemovePaging(CurrentQuery.Query.Expression);
               LoadOperation<OrderAcknowledgement>  loadOp = this.customersDataSource.DomainContext.Load<OrderAcknowledgement>((EntityQuery<OrderAcknowledgement>)CurrentQuery);
               loadOp.Completed += (o, e) =>
                   {
                       if (!loadOp.HasError)
                       {
                           ExportOrders = loadOp.Entities.ToList();
                       }
                   };
           }
    I need to remove from the current query the information regards the paging (skip, take) in order to retrieve all entities and send to another procedure.
    i don't want to show in the grid the data retrieved from the export method. In the grid only the
    question is: how do i use the paging remover in order to remove the paging filter inside the queryexpression?

    thanks
    gio
  9. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 02 Mar 2011 Link to this post

    Hello Giovanni,

    Since you want to export the data, the best option would be to create another DomainContext that will be used solely for that purpose. Here is how I did this:

    private void OnExportButtonClick(object sender, System.Windows.RoutedEventArgs e)
    {
        var exportContext = new NorthwindDomainContext();
         
        // The Where and Sort are our extension methods that will
        // transform an EntityQuery<T> based on the supplied descriptors.
        var exportQuery = exportContext.GetCustomersQuery()
            .Where<Customer>(this.radGridView.FilterDescriptors)
            .Sort<Customer>(this.radGridView.SortDescriptors)
            .IncludeTotalCount<Customer>(true);
     
        exportContext.Load<Customer>(exportQuery, LoadBehavior.RefreshCurrent, this.OnExportCompleted, exportQuery);
    }
     
    private void OnExportCompleted(LoadOperation<Customer> loadOperation)
    {
        if (!loadOperation.HasError)
        {
            this.debugTextBox.Text += "Exported " + loadOperation.TotalEntityCount + " customers:\r\n";
             
            var exported = loadOperation.Entities.ToList();
            foreach (var customer in exported.Cast<Customer>())
            {
                this.debugTextBox.Text += customer.ContactName + "\r\n";
            }
        }
    }

    I have prepared and attached sample project that demonstrates this.

    I hope this helps.

    Regards,
    Ross
    the Telerik team
    Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
Back to Top
DevCraft banner