CRM provides for multiple methods of querying data from the API FetchXML, QueryExpressions, Linq, and OData. Each of these technologies has their time and place. This web page has a good chart showing the features of each compared to straight up SQL in the CRM 2011 SDK. (http://blogs.msdn.com/b/crminthefield/archive/2013/01/14/crm-2011-sdk-query-limitations-by-api.aspx).
Using Linq has a few advantages.
1) I personally think it is the direction Microsoft is going with their data retrieval technologies. Look where Entity Framework has come in the last few years.
2) The ability to use Lamda expressions in where clauses as the SDK example code shows ('%pathtosdk%\SDK\SampleCode\CS\GeneralProgramming\Queries\LINQExamples.cs' line 562).
3) Linq can be used in Late Bound or Early Bound coding.
To use Linq you need a reference to the OrganizationServiceContext. To get the OrganizationServiceContext you need a reference to an IOrganizationService.
This code is typical to most plugins:
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
To get the OrgnizationServiceContext we add one line of code:
OrganizationServiceContext serviceContext = new OrganizationServiceContext(service);
Now that we have a reference to the context we can start using Linq to query CRM.
Take the following three samples below that are querying the CRM sample data on the Account entity. We are getting the accounts that begin with the letter 'C'.
For our first example we will use the QueryExpression method of querying CRM:
QueryExpression accountExpression = new QueryExpression('account');
ConditionExpression beginsWithExpression = new ConditionExpression('name', ConditionOperator.BeginsWith, 'C');
FilterExpression filter = new FilterExpression();
filter.Conditions.Add(beginsWithExpression);
filter.FilterOperator = LogicalOperator.And;
accountExpression.Criteria = filter;
ColumnSet columns = new ColumnSet(newstring[] {'name'});
accountExpression.ColumnSet = columns;
EntityCollection queryAccounts = orgService.RetrieveMultiple(accountExpression);
if (queryAccounts.Entities != null)
{
foreach (var e in queryAccounts.Entities)
{
Console.WriteLine(e.GetAttributeValue<string>('name'));
}
}
This second example is using Linq Late Bound to query the Account:
var accounts = from account in context.CreateQuery('account')
where account.GetAttributeValue<string>('name').StartsWith('C')
select account.GetAttributeValue<string>('name');
foreach (var a in accounts)
{
Console.WriteLine(a);
}
If you are fortunate enough to be in a situation where you can you can use Early Bound entities the Linq syntax becomes even easier:
var accounts = from account in context.AccountSet
where account.Name.StartsWith('C')
select new {account.Name};
foreach (var a in accounts)
{
Console.WriteLine(a.Name);
}
All three of these return the same values:
City Power & Light (sample)
Contoso Pharmaceuticals (sample)
Coho Winery (sample)
These examples show how using Linq can reduce the number of lines of code, reduce the complexity of the code, and make the code easier to maintain long term. Those three qualities make Linq the default choice when working with data from CRM.