I'm not a developer - don't even play one on TV - but sometimes our internal CRM implementation needs some functionality and I'm able to cobble enough code from other places to make something work. Since I hadn't seen anything out there for this particular use case, I thought it was worthwhile to share more broadly.
BUSINESS PROBLEMWe have had challenges at time with the waiting workflow state and the overhead associated with having all of our contracts in a waiting state, to "wait" to be marked historical automatically when the contract ends. To avoid this, we wanted to put something in place that can run daily to check to see which contracts are about to expire or have expired. Since I'm not really a developer, I wanted to put as much of the code in a workflow as possible, and leave the console app simple - it just reads in records for an entity and fires the appropriate workflow. The workflow handles the sending of emails, updating records, etc.
DEVELOPMENT STEPSThese instructions may be fairly basic, but it was the exact instructions I needed in order to make this work. These steps assume that you have Visual Studio 2010 installed on your machine, the CRM SDK and .NET 4.0.
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.ServiceModel;using Microsoft.Xrm.Sdk;using Microsoft.Xrm.Sdk.Client;using System.ServiceModel.Description;using System.Net;using Microsoft.Xrm.Sdk.Query;using Microsoft.Crm.Sdk.Messages;
ClientCredentials Credentials = new ClientCredentials();
Credentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
string servername = "SERVERNAME";
string orgname = "ORGANIZATION";
Uri OrganizationUri = new Uri("http://" + servername + "/" + orgname + "/XRMServices/2011/Organization.svc");
Uri HomeRealmUri = null;
using (OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(OrganizationUri, HomeRealmUri, Credentials, null))
string getContracts = @"
<attribute name='new_pfecontractid' />
<condition attribute='new_status' operator='eq' value='1' />
FetchExpression fe = new FetchExpression(getContracts);
EntityCollection results = serviceProxy.RetrieveMultiple(fe);
var _workflowId = new Guid("fb126b05-ddc3-4f8e-8e1f-54d1e0b5fe8e");
foreach (var c in results.Entities)
string contractid = c.Attributes["new_pfecontractid"].ToString();
_pfecontractId = new Guid(contractid);
// Create an ExecuteWorkflow request.
ExecuteWorkflowRequest request = new ExecuteWorkflowRequest()
WorkflowId = _workflowId, EntityId = _pfecontractId
// Execute the workflow.
ExecuteWorkflowResponse response =
// System.Console.WriteLine("Successfully executed workflow");
* If you received a build error related to the Target .NET Framework, you may have to change your project's default framework. To do that, you'll need to open the Project properties and change the value to .NET Framework 4:
Please keep in mind that this will only work on the first 5000 rows. In order to loop through all records, you need to create a loop on the retrieve using the paging cookie.
Great Article ..
NullReferenceException always in EntityCollection
Can you share with us on how to do the looping to get all records not just 5000 rows?
The code Eric wrote above will only pull in 5000 rows - however, hit up NuGet and download the PFE Core library - we have an override for RetrieveMultiple allowing you to request all pages from all rows. Source code is on pfexrmcore.codeplex.com - we use standard paging logic where we iterate pulling back 5000 at a time until there are no more pages - but the library will do that work for you.
Thanks for reading!