This is a migrated thread and some comments may be shown as answers.

QueryableDataServiceCollectionView - The DataServiceCollection to be tracked must contain entity typed elements with at least one key property.

10 Answers 568 Views
DataServiceDataSource
This is a migrated thread and some comments may be shown as answers.
Stevo
Top achievements
Rank 1
Stevo asked on 08 Oct 2013, 08:15 AM
Hi,

I'd like to display data from database using an OData endpoint in the GridView. For this I've decided to use the QueryableDataServiceCollectionView, passing the DataServiceContext and DataServiceQuery into constructor.

For OData, I have a standard setup of Web Api OData Service endpoint and WCF Data Services 5 WPF Client. Model (DTO) looks like this:

[DataServiceKey("FactTradeHeaderIdentifier")]
    public class TradeHeaderModel
    {
        [Key]
        [DataMember(IsRequired = true)]               
        public int FactTradeHeaderIdentifier { get; set; }
     
        ...
    }

And the autogenerated client side counterpart like this:

    /// <summary>
    /// There are no comments for Edft.Regulatory.Tracker.Service.Web.ApiModels.TradeHeaderModel in the schema.
    /// </summary>
    /// <KeyProperties>
    /// FactTradeHeaderIdentifier
    /// </KeyProperties>
    [global::System.Data.Services.Common.EntitySetAttribute("TradeHeaders")]
    [global::System.Data.Services.Common.DataServiceKeyAttribute("FactTradeHeaderIdentifier")]
    public partial class TradeHeaderModel : global::System.ComponentModel.INotifyPropertyChanged
    {
        /// <summary>
        /// There are no comments for Property FactTradeHeaderIdentifier in the schema.
        /// </summary>
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
        public int FactTradeHeaderIdentifier
        {
            get
            {
                return this._FactTradeHeaderIdentifier;
            }
            set
            {
                this.OnFactTradeHeaderIdentifierChanging(value);
                this._FactTradeHeaderIdentifier = value;
                this.OnFactTradeHeaderIdentifierChanged();
                this.OnPropertyChanged("FactTradeHeaderIdentifier");
            }
        }
 
        ...
}

When loading data into the QueryableDataServiceCollectionView 

var ds = new QueryableDataServiceCollectionView<TradeHeaderModel>(apiService.Container, apiService.Container.TradeHeaders);

I get this error:

System.ArgumentException: The DataServiceCollection to be tracked must contain entity typed elements with at least one key property. The element type 'Edft.Regulatory.Tracker.Presentation.CrossCutting.ServiceClient.ApiODataService.TradeHeaderModel' does not have any key property.
   at System.Data.Services.Client.DataServiceCollection`1.StartTracking(DataServiceContext context, IEnumerable`1 items, String entitySet, Func`2 entityChanged, Func`2 collectionChanged)
   at System.Data.Services.Client.DataServiceCollection`1..ctor(DataServiceContext context)
   at Telerik.Windows.Controls.DataServices.DataServiceCollection`1..ctor(DataServiceContext context)
   at Telerik.Windows.Data.QueryableDataServiceCollectionView`1..ctor(DataServiceContext dataServiceContext, DataServiceQuery`1 dataServiceQuery)
   at Edft.Regulatory.Tracker.Presentation.Modules.Dashboard.ViewModels.TradeHeaderViewModel.<LoadDataAsync>d__1f.MoveNext() in d:\TFS\Regulatory\Tracker\Dev\Codebase\Edft.Regulatory.Tracker.Presentation.Modules.Dashboard\ViewModels\TradeHeaderViewModel.cs:line 272

Note that the DataServiceKeyAttribute is defined on both client and server models.

Any ideas? 


Edit: Using the Telerik.Windows.Controls.DataServices50 version

Thanks,
Stevo

10 Answers, 1 is accepted

Sort by
0
Rossen Hristov
Telerik team
answered on 08 Oct 2013, 01:05 PM
Hello,

We simply use the standard Microsoft class DataServiceCollection as described here. We don't actually perform any of the WCF Data Services work -- we simply append Where and OrderBy's on the query -- that's it. Our component simply steps on top of the WCF Data Services stack and its only job is to append those Where and OrderBy clauses to the DataServiceQuery<T>. It does not do anything else -- all the job is done by the DataServiceContext, DataServiceCollection and DataServiceQuery.

From the stack trace I can see that it is the DataServiceCollection that complains about the query.
 
I have the following question. If you remove all Telerik components, can you successfully create and use such a DataServiceCollection<T> to make queries as described in this article?

Please, let me know what the results are.

Regards,
Rossen Hristov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Stevo
Top achievements
Rank 1
answered on 08 Oct 2013, 01:26 PM
Hi Rossen,

I've tried to use the DataServiceCollection<T> directly, passing it DataServiceQuery<T> appended with same .Where(...) (which makes it IQueryable<T>) and that works fine.

However that strips away the possibility of doing server side sorting and paging.

Regards,
Stevo
0
Rossen Hristov
Telerik team
answered on 08 Oct 2013, 01:59 PM
Hello,

I don't really think that this exception is caused by our components. In fact I am sure that it is not by reading the stack trace you posted. The exception is thrown the very moment we try to create this DataServiceCollection with the supplied arguments.

Here is what we do in our very thin wrapper:

var something = new DataServiceCollection<TradeHeaderModel>(apiService.Container);

And at exactly this point it throws the exception. I am baffled by the fact that you can successfully do the same thing "outside" and not get any exceptions. Is this so?

Regards,
Rossen Hristov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Stevo
Top achievements
Rank 1
answered on 09 Oct 2013, 11:33 AM
Hi,

just tried:

var data = new DataServiceCollection<TradeHeaderModel>(apiService.Container.TradeHeaders); // Works Fine

var data = new QueryableDataServiceCollectionView<TradeHeaderModel>(apiService.Container, apiService.Container.TradeHeaders); //Crashes complaining about the missing key

Note that what you've suggested
var something = new DataServiceCollection<TradeHeaderModel>(apiService.Container);
Does not do anything, since container does not have any data as such

Regards,
Stevo

0
Rossen Hristov
Telerik team
answered on 09 Oct 2013, 01:51 PM
Hello,

The thing I suggested is exactly what we do in our constructor. Here is an excerpt from our souce code:

this.wcfDataServiceCollection = new WCF.DataServiceCollection<TEntity>(this.context);

Where TEntity in this case is TradeHeaderModel and this.context is the instance of DataServiceContext<T> that you supply in the constructor. It learns about the type from the generic argument as we will see later.

Once we send the query to the server and receive the response we call DataServiceCollection.Load method to load all received entities in the DataServiceCollection. We simply follow what is written in MSDN here.

Anyway, here is the stacktrace again:

System.ArgumentException: The DataServiceCollection to be tracked must contain entity typed elements with at least one key property. The element type 'Edft.Regulatory.Tracker.Presentation.CrossCutting.ServiceClient.ApiODataService.TradeHeaderModel' does not have any key property.
   at System.Data.Services.Client.DataServiceCollection`1.StartTracking(DataServiceContext context, IEnumerable`1 items, String entitySet, Func`2 entityChanged, Func`2 collectionChanged)
   at System.Data.Services.Client.DataServiceCollection`1..ctor(DataServiceContext context)
   at Telerik.Windows.Controls.DataServices.DataServiceCollection`1..ctor(DataServiceContext context)
   at Telerik.Windows.Data.QueryableDataServiceCollectionView`1..ctor(DataServiceContext dataServiceContext, DataServiceQuery`1 dataServiceQuery)
   at Edft.Regulatory.Tracker.Presentation.Modules.Dashboard.ViewModels.TradeHeaderViewModel.<LoadDataAsync>d__1f.MoveNext() in d:\TFS\Regulatory\Tracker\Dev\Codebase\Edft.Regulatory.Tracker.Presentation.Modules.Dashboard\ViewModels\TradeHeaderViewModel.cs:line 272

The things in yellow is the souce code I pasted above. We simply create a new instance of a generic System.Data.Services.Client.DataServiceCollection<TradeHeaderModel> by passing your context to the constructor. That is all. I reflected their assembly and here is the constructor:

public DataServiceCollection(DataServiceContext context, IEnumerable<T> items, TrackingMode trackingMode, string entitySetName, Func<EntityChangedParams, bool> entityChangedCallback, Func<EntityCollectionChangedParams, bool> collectionChangedCallback)
{
    if (trackingMode != TrackingMode.AutoChangeTracking)
    {
        if (items != null)
        {
            this.Load(items);
        }
    }
    else
    {
        if (context == null)
        {
            if (items != null)
            {
                context = DataServiceCollection<T>.GetContextFromItems(items);
            }
            else
            {
                this.trackingOnLoad = true;
                this.entitySetName = entitySetName;
                this.entityChangedCallback = entityChangedCallback;
                this.collectionChangedCallback = collectionChangedCallback;
            }
        }
        if (!this.trackingOnLoad)
        {
            if (items != null)
            {
                DataServiceCollection<T>.ValidateIteratorParameter(items);
            }
            this.StartTracking(context, items, entitySetName, entityChangedCallback, collectionChangedCallback);
            return;
        }
    }
}

And here is the StartTracking method I decompiled:

private void StartTracking(DataServiceContext context, IEnumerable<T> items, string entitySet, Func<EntityChangedParams, bool> entityChanged, Func<EntityCollectionChangedParams, bool> collectionChanged)
{
    if (BindingEntityInfo.IsEntityType(typeof(T), context.Model))
    {
        this.observer = new BindingObserver(context, entityChanged, collectionChanged);
        if (items != null)
        {
            try
            {
                this.InternalLoadCollection(items);
            }
            catch
            {
                this.observer = null;
                throw;
            }
        }
        this.observer.StartTracking<T>(this, entitySet);
        this.rootCollection = true;
        return;
    }
    else
    {
        throw new ArgumentException(Strings.DataBinding_DataServiceCollectionArgumentMustHaveEntityType(typeof(T)));
    }
}


For some mystic reason the thing that tracks entities thinks that your class TradeHeaderModel does not have at least one Key property or that it is not an Entity at all. This is really beyond me. If you try with a dummy demo with AdventureWorks or Northwind you will see that all goes well, so there must be something funny in this TradeHeaderModel class but I do not know what it is.

I really have no idea why the System.Data.Services.Client.DataServiceCollection does not like your TradeHeaderModel class.

So basically you are saying that if you write this
exact line somewhere in your project:

var something = new System.Data.Services.Client
DataServiceCollection<TradeHeaderModel>(<<your DataServiceContext instance here>>);


and it does not blow? 

That is very weird since we do this exact same thing and it blows up as you can see.

Anyway, unless I am able to reproduce this locally, I can't really guess why Microsoft's System.Data.Services.Client.DataServiceCollection blows up.

Also, please make sure that you are using WCF Data Services 5.5.0 or above which is the out-of-band version that our assembly Telerik.Windows.Controls.DataServices50.dll for .NET 4.5. Only the .NET 4.5 version of our assembly can target WCF Data Services 5 and above since Microsoft decided to start releasing WCF Data Services out-of-band and we can't really create a build for each of their version that are distributed via NuGet.

Another thing -- if you don't do any CRUD operations, you don't really need our component - you can directly bind RadGridView to an IQueryable (i.e. the DataServiceQuery<T> on your context) and it will do all of its stuff on this IQueryable. This is described here.

If you can help me reproduce this locally I will be more than glad to take a look. With the information I currently have my hands are kind of tied.

Regards,
Rossen Hristov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Stevo
Top achievements
Rank 1
answered on 09 Oct 2013, 02:22 PM
Hi,

>>The thing I suggested is exactly what we do in our constructor. Here is an excerpt from our souce code:

this.wcfDataServiceCollection = new WCF.DataServiceCollection<TEntity>(this.context);

Where TEntity in this case is TradeHeaderModel and this.context is the instance of DataServiceContext<T> that you supply in the constructor. It learns about the type from the generic argument as we will see later.

Once we send the query to the server and receive the response we call DataServiceCollection.Load method to load all received entities in the DataServiceCollection. We simply follow what is written in MSDN here.

Looking at MSDN, I don't understand why are you guys using that constructor. It's not meant for loading from server. http://msdn.microsoft.com/en-us/library/ee652763.aspx 

You must be loading data somehow differently (and that's where I suppose the problem happens). All the MSDN examples show passing it the actual query:

http://msdn.microsoft.com/en-us/library/ee373844.aspx
http://msdn.microsoft.com/en-us/library/ee474331.aspx
http://msdn.microsoft.com/en-us/library/ee373846.aspx

>>var something = new System.Data.Services.Client
DataServiceCollection<TradeHeaderModel>(<<your DataServiceContext instance here>>);

and it does not blow?
 

That does not do anything, and it's not mean to do http://msdn.microsoft.com/en-us/library/ee652763.aspx 

>>Another thing -- if you don't do any CRUD operations, you don't really need our component - you can directly bind RadGridView to an IQueryable (i.e. the DataServiceQuery<T> on your context) and it will do all of its stuff on this IQueryable. This is described here.

It's runs the queries on the UI thread, which we can't have for obvious reasons.

Regards,
Stevo

0
Accepted
Rossen Hristov
Telerik team
answered on 09 Oct 2013, 03:45 PM
Hello,

The process is quite simple actually. We create an empty DataServiceCollection<T> in the very beginning. Then each time a load is requested for some reason we basically do the following. We call DataServiceContext.BeginExecute by passing the required query. This kicks off an async operation. After a while data comes back to the client. We then call context.EndExecute and obtain the entities. We then stick all of those entities in the DataServiceCollection by callind its Load method so it starts tracking them. Here is the complete source code of our thin wrapper class called Telerik.Windows.Controls.DataServices.DataServiceCollection. Note that while the name is the same, this is our class and not the System.Data.Services.Client.DataServiceCollection, which is the class we wrap and is called wcfDataServiceCollection in the source code:

using System;
using System.Collections;
using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Diagnostics;
using System.Data.Services.Client;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using Telerik.Windows.Data;
using WCF = System.Data.Services.Client;
 
namespace Telerik.Windows.Controls.DataServices
{
    /// <summary>
    /// DataServiceCollection.
    /// </summary>
    internal class DataServiceCollection<TEntity> :
        ObservableItemCollection<TEntity>,
        INotifyPropertyChanged
        where TEntity : class, INotifyPropertyChanged
    {
        private readonly DataServiceContext context;
        private readonly WCF.DataServiceCollection<TEntity> wcfDataServiceCollection;
 
        public event EventHandler<LoadOperationCompletedEventArgs<TEntity>> LoadCompleted;
        private SynchronizationContext syncContext;
        private IAsyncResult currentLoadOperation;
        private bool cancelledRequest;
        private bool ignoreCollectionChangedOverride;
        private int totalItemCount = -1;
        private bool isLoading;
        private bool hasChanges;
 
        /// <summary>
        /// Gets the total item count.
        /// </summary>
        /// <value>The total item count.</value>
        public int TotalItemCount
        {
            get
            {
                return this.totalItemCount;
            }
            private set
            {
                if (this.totalItemCount != value)
                {
                    this.totalItemCount = value;
                    this.OnPropertyChanged("TotalItemCount");
                }
            }
        }
 
        public bool IsLoading
        {
            get
            {
                return this.isLoading;
            }
            private set
            {
                if (this.isLoading != value)
                {
                    this.isLoading = value;
                    this.OnPropertyChanged("IsLoading");
                }
            }
        }
         
        public bool HasChanges
        {
            get
            {
                return this.hasChanges;
            }
            private set
            {
                if (this.hasChanges != value)
                {
                    this.hasChanges = value;
                    this.OnPropertyChanged("HasChanges");
                }
            }
        }
         
        /// <summary>
        /// Initializes a new instance of the DataServiceCollection class.
        /// </summary>
        /// <param name="context">The context.</param>
        public DataServiceCollection(DataServiceContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
 
            this.context = context;
            this.wcfDataServiceCollection = new WCF.DataServiceCollection<TEntity>(this.context);
        }
 
        public void SetSynchronizationContext(SynchronizationContext synchronizationContext)
        {
            this.syncContext = synchronizationContext;
        }
 
        public void Load(LoadContext loadContext)
        {
            this.wcfDataServiceCollection.Clear(); 
             
            var query = loadContext.DataServiceQuery;
            var queryRequestUri = query.RequestUri;
 
            this.IsLoading = true;
             
            // Any other option will break the inner logic.
            if (this.context.MergeOption != MergeOption.OverwriteChanges)
            {
                throw new InvalidOperationException("DataServiceContext.MergeOption can only be MergeOption.OverwriteChanges.");
            }
 
            this.currentLoadOperation = this.context.BeginExecute<TEntity>(queryRequestUri
                , this.OnResultsReceived
                , loadContext);
        }
 
        public void CancelLoad()
        {
            if (this.currentLoadOperation != null
                && !this.currentLoadOperation.IsCompleted)
            {
                this.cancelledRequest = true;
                try
                {
                    this.context.CancelRequest(this.currentLoadOperation);
                }
                catch (WebException)
                {
                }
            }
        }
 
        /// <summary>
        /// Called when the results arrive asynchronously from the server.
        /// </summary>
        /// <remarks>
        /// Since there is no guarantee that this method will be invoked on the UI thread,
        /// we have to marshal the response operation back to the main application thread
        /// (the UI thread). Code that accesses entities, accesses the DataServiceContext or
        /// enumerates results of LINQ queries needs to happen on the UI thread.
        /// </remarks>
        /// <param name="result">The result.</param>
        private void OnResultsReceived(IAsyncResult result)
        {
            this.syncContext.Post(delegate(object state)
            {
                this.SynchronizeContextLoadCompleted(result);
            }, null
            );
        }
 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        private void SynchronizeContextLoadCompleted(IAsyncResult result)
        {
            if (this.cancelledRequest)
            {
                this.cancelledRequest = false;
                this.currentLoadOperation = null;
                 
                this.IsLoading = false;
                var args = new LoadOperationCompletedEventArgs<TEntity>(Enumerable.Empty<TEntity>()
                    , null
                    , (LoadContext)result.AsyncState
                    , true
                    , null
                    , 0);
                this.OnLoadCompleted(args);
            }
            else
            {
                QueryOperationResponse<TEntity> response = null;
 
                try
                {
                    response = (QueryOperationResponse<TEntity>)this.context.EndExecute<TEntity>(result);
                }
                catch (Exception exception)
                {
                    this.IsLoading = false;
                    var args = new LoadOperationCompletedEventArgs<TEntity>(Enumerable.Empty<TEntity>()
                        , response
                        , (LoadContext)result.AsyncState
                        , false
                        , exception
                        , 0);
                    this.OnLoadCompleted(args);
 
                    return;
                }
 
                if (response != null)
                {
                    this.ProcessResponse(response, (LoadContext)result.AsyncState);
                }
            }
        }
         
        private void ProcessResponse(QueryOperationResponse<TEntity> response, LoadContext loadContext)
        {
            //// Load the entities that have just arrived in the "state"
            //// DataServiceCollection so it can start "tracking" them.
            //// response is an IEnumerable<T> and contains the entities
            this.wcfDataServiceCollection.Load(response);
 
            var continuation = response.GetContinuation();
            if (continuation != null)
            {
                // Send a request for the next server page.
                this.currentLoadOperation = this.context.BeginExecute<TEntity>(continuation
                    , this.OnResultsReceived, loadContext);
            }
            else
            {
                this.IsLoading = false;
             
                // This was the last page, so copy all the entities to "this".
                this.SuspendNotifications();
 
                this.ignoreCollectionChangedOverride = true;
                this.Clear();
                this.AddRange(this.wcfDataServiceCollection);
                this.ignoreCollectionChangedOverride = false;
                 
                try
                {
                    this.TotalItemCount = (int)response.TotalCount;
                }
                catch (InvalidOperationException)
                {
                    // The server refuses to tell us the total count for some reason.
                    // Most probably the DataServiceBehavior has its
                    // AcceptCountRequests set to false.
                    // Set the TotalItemCount to be as much as we know.
                    // Nothing better that we can do. Bad server, bad!
                    this.TotalItemCount = this.Count;
                }
                 
                this.ResumeNotifications();
            }
 
            var args = new LoadOperationCompletedEventArgs<TEntity>(this.wcfDataServiceCollection
                , response
                , loadContext
                , false
                , null
                , this.TotalItemCount);
            this.OnLoadCompleted(args);
        }
 
        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            base.OnCollectionChanged(e);
 
            if (this.ignoreCollectionChangedOverride)
            {
                return;
            }
 
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    foreach (TEntity item in e.NewItems)
                    {
                        this.wcfDataServiceCollection.Add(item);
                        this.TotalItemCount++;
                    }
                    break;
                case NotifyCollectionChangedAction.Remove:
                    foreach (TEntity item in e.OldItems)
                    {
                        this.wcfDataServiceCollection.Remove(item);
                        this.TotalItemCount--;
                    }
                    break;
                case NotifyCollectionChangedAction.Replace:
                    break;
                case NotifyCollectionChangedAction.Reset:
                    break;
                default:
                    break;
            }
 
            this.RefreshHasChanges();
        }
 
        protected override void OnItemChanged(ItemChangedEventArgs<TEntity> e)
        {
            base.OnItemChanged(e);
 
            this.RefreshHasChanges();
        }
 
        public void RefreshHasChanges()
        {
            this.HasChanges = this.context.HasChanges();
        }
 
        private void OnPropertyChanged(string propertyName)
        {
            this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }
 
        protected virtual void OnLoadCompleted(LoadOperationCompletedEventArgs<TEntity> args)
        {
            var handler = this.LoadCompleted;
            if (handler != null)
            {
                handler(this, args);
            }
        }
    }
}

Yes, creating a new empty instance of DataServiceCollection<T>(context) does not do anything immediately (at this exact moment) but this is where your exception occurs, which is why I asked you several times for to simply try this line of code outside our component, which you for some reason are refusing to do. I can't really fix an exception that is thrown by WCF Data Services when this line is written:

var sth = new DataServiceCollection<T>(context);

This is one of the constructors that Microsoft provides (so it has a point after all) and our software happens to use this constructor for the reasons I explained above. This constructor thows an exception. All we pass to this constructor are the two thing provied by you -- the generic type TradeHeaderMode and the DataServiceContext that you have provided. We don't do anything in between.

This is why I asked you several times to just execute this line:

var sth = new DataServiceCollection<T>(context);

And tell me what the results are. Up until now I have not received an answer.

If you can provide a runnable sample project which I can debug locally I might be able to help you. But unless I have that I really don't know what else I can do about this issue.

Regards,

Rossen Hristov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Stevo
Top achievements
Rank 1
answered on 29 Oct 2013, 05:51 PM
Hi,

I've started drilling into the problem again, and it just started working. I'm not sure what has changed in the meantime, I remember updating Telerik dlls to latest version, maybe some other references have changed and the problem disappeared.

Thanks for your support,
Stevo
0
Mohan
Top achievements
Rank 1
answered on 01 Jul 2020, 03:41 PM

Hi Rossen, 

We are using QueryableDataServiceCollectionView with RadGridView and autoLoad set to true.

While loading the gridview, in the fiddler we are observing one main request with all the required filters on the query  and many individual requests to the server (one for each item). Is this expected behaviour?

By doing this.wcfDataServiceCollection.Load(response) in the ProcessResponse(QueryOperationResponse<TEntity> response, LoadContext loadContext), it is triggering multiple requests to the server as the number of items. Shouldn't it just load from the response obtained?

 

As we are fetching the response (all the required items) from the DataServiceQuery, why are we again requesting the server for all the individual items?
        

0
Vladimir Stoyanov
Telerik team
answered on 06 Jul 2020, 10:52 AM

Hello Mohan,

Thank you for the shared information. 

My current understanding is that you are filtering the RadGridView, which is populated with the help of a QueryableDataServiceCollectionView and you are observing a request in Fiddler for each of the filtered items. Feel free to correct me, if I am wrong and elaborate a bit on the scenario. 

I tested this on my end, however I was not able to replicate the same behavior. That is why I am attaching the sample project that I used for testing. Can you check it out and see how it differs from the setup on your end? Should you need any further assistance, can you modify the project in order to demonstrate your scenario and send it over in a new support ticket (since project files cannot be attached to forum posts)? This will hopefully allow me to investigate the behavior and further assist you. 

Regards,
Vladimir Stoyanov
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Tags
DataServiceDataSource
Asked by
Stevo
Top achievements
Rank 1
Answers by
Rossen Hristov
Telerik team
Stevo
Top achievements
Rank 1
Mohan
Top achievements
Rank 1
Vladimir Stoyanov
Telerik team
Share this question
or