Reputation: 10244
I'm using Microsoft CRM 2011 web services to retrieve a list of activities but the request is timing out due to the amount of data. I'm implementing paging and tried doing yield return, but then I got an 'The connection was unexpectedly closed' error.
public IEnumerable<LinkedActivity> GetActivitiesForUser() {
var svc = GetCrmService();
var cols = new ColumnSet();
cols.Attributes = new[] { "activityid", "addressused", "scheduledstart", "scheduledend", "partyid", "activitypartyid", "participationtypemask", "ownerid" };
var query = new QueryExpression();
query.EntityName = EntityName.activityparty.ToString();
query.ColumnSet = cols;
LinkEntity link = new LinkEntity();
//link.LinkCriteria = filter;
link.LinkFromEntityName = EntityName.activitypointer.ToString();
link.LinkFromAttributeName = "activityid";
link.LinkToEntityName = EntityName.activityparty.ToString();
link.LinkToAttributeName = "activityid";
query.LinkEntities = new[] {link};
var activities = svc.RetrieveMultiple(query);
var entities = new List<ICWebServices.activityparty>();
RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse) svc.Execute(request);
//var pointers = new List<activitypointer>();
foreach (activityparty c in activities.BusinessEntities)
{
//yield return c; - this returned an error "The connection was unexpectedly closed"
entities.Add(((activityparty)c));
}
To implement paging I'm using:
var activities = GetActivities();
var offset = startRowIndex > 0 ? activities.Skip(startRowIndex) : activities;
var limited = limit > 0 ? offset.Take(limit) : offset.Take(100);
return limited.ToList();
Is there any way I can just return the first 100 items?
Upvotes: 0
Views: 1718
Reputation: 1048
Why not use LINQ, and paging in your app?
Linq has this stuff natively, and MS has both REST and SOAP endpoints.
I have not tested, but I suscpect that the REST endpoint can be used directly with paging.
public static class PagingExtensions
{
//used by LINQ to SQL
public static IQueryable<TSource> Page<TSource>(this IQueryable<TSource> source, int page, int pageSize)
{
return source.Skip((page - 1)*pageSize).Take(pageSize);
}
//used by LINQ
public static IEnumerable<TSource> Page<TSource>(this IEnumerable<TSource> source, int page, int pageSize)
{
return source.Skip((page - 1)*pageSize).Take(pageSize);
}
}
class Program
{
static void Main(string[] args)
{
List<string> names = new List<string>();
names.AddRange(new string[]{"John","Frank","Jeff","George","Bob","Grant", "McLovin"});
foreach (string name in names.Page(2, 2))
{
Console.WriteLine(name);
}
}
}
Upvotes: 0
Reputation: 17956
tyrongower is correct. Also, you should wrap your service in a using statement to ensure its properly disposed of.
Upvotes: 0
Reputation: 2429
You need to define a PageInfo your QueryExpression
http://msdn.microsoft.com/en-us/library/aa683424.aspx
Upvotes: 2