3
votes

I am using this C# SDK to get data from Dynamics CRM 2011: https://msdn.microsoft.com/en-us/library/gg695803(v=crm.5).aspx

I need to read all the Accounts from it and to read the Activities associated with it (actually, only the last Closed and Open Activity).

To get the accounts I am using the following code:

var accounts = xrm.AccountSet
                .Select(acc => new
                {
                    name = acc.Name,
                    guid = acc.AccountId,
                    parent = acc.ParentAccountId,
                    number = acc.AccountNumber,
                    website = acc.WebSiteURL,
                });

This way has been suggested in this question: Retrieve list of all accounts in CRM through C#?

The problem is, I can't find a way to get the Activities. Is there a field associated with Activities? All I can find is a separate Activity Entity with it's own fields in the Dynamics CRM 2011 Solution.

Also I am new to C#.

EDIT: Thanks to Jordi, I now seem to be able to get a specific type of Activity using this:

public class AccountTask
        {
            public string account;
            public string task;
        }

var accountsAndTasks = (from t in xrm.CreateQuery<Task>() join a in xrm.CreateQuery<Account>() on t.RegardingObjectId.Id equals a.AccountId select new AccountTask {

               account = a.Name,
               task = t.OwnerId.Name.ToString()
}).ToList();

Now, is there a way to get all Activity types at once for each Account?

And, is it possible to only get the latest Open and Closed Activity for each Account?

2
Could you please describe the task more detailed? Do you need to fetch activities where an account specified in an activity "Regarding" field?Alex
@Alex, I need to fetch all Activities to each existing Account. I guess the Account is specified in the Regarding Field, but I am not sure, that is my question, how to match Accounts and Activities?ivan_bilan

2 Answers

3
votes

The RegardingObjectId field is one of the fields that relates an activity entity record to an account entity record.
You may fetch activity entity records like this:

var activityBaseList = serviceContext.CreateQuery<Activity>()
            .Where(x => x.RegardingObjectId.Id == accountId).ToList();

This is a base entity and it has only basic information about the activity. If you need more information about each activity record ( and in most cases you do need that) then you will have to make multiple queries with different activity types. Like this:

var emailActivityList = serviceContext.CreateQuery<Email>()
            .Where(x => x.RegardingObjectId.Id == accountId).ToList();
var taskActivityList = serviceContext.CreateQuery<Task>()
            .Where(x => x.RegardingObjectId.Id == accountId).ToList();
//and so on

I'd prefer using QueryBase requests because in that case you may combine queries into one ExecuteMultipleRequest call to IOrganizationService to improve the performance, but be aware of limitations: info about ExecuteMultipleRequest limitations.

UPDATE

I did not see your other question in the bottom. If you need to get only open activities you will need to add x.StateCode == 0 to each query written above if you need only closed activities you will need to add x.StateCode == 2. For example, retrieve only open email activities:

var emailActivityList = serviceContext.CreateQuery<Email>()
            .Where(x => x.RegardingObjectId.Id == accountId && x.StateCode == 0).ToList();

Here is the list of all out of the box state codes and statuses for all entities.

If you need to retrieve let's say only recent open activities (you will define how recent you need by yourself) you make the following call:

var createdOnFilter = DateTime.Now.AddDays(-1); //change it as you need it
var emailActivityList = serviceContext.CreateQuery<Email>()
            .Where(x => x.RegardingObjectId.Id == accountId && 
                        x.StateCode == 0 && 
                        x.CreatedOn >= createdOnFilter)
            .ToList();

This is a very basic code and there is plenty information about it on the WEB.

1
votes

It looks like a join what you need.

There are different entities depending on the Activity type.

The following example is for Task activities, others would be similar.

//This will pull all the related tasks
var accountsAndTasks = (from t in xrm.CreateQuery<Task>()
            join a in xrm.CreateQuery<Account>() on t.RegardingObjectId.Id  equals a.AccountId
           select new AccountTask {
                account = a,
                task = t
           }).ToList();

If you need other examples of rather complex queries, please check this example on Git.