The F# 3.0 Microsoft Dynamics CRM Type Provider Sample - Strongly-typed enterprise-scale customer data made simple

[ Update: the CRM type provider is now available as the FSharpx.TypeProviders.Xrm NuGet package. The namespace has changed from "Samples" to "FSharpx". Further information on the F# Community can be found at fsharp.org    ]  

Part 1 - The Microsoft Dynamics CRM Type Provider Sample
Part 2 - The Microsoft Dynamics CRM Type Provider Sample - Static Parameters
Part 3 - The Microsoft Dynamics CRM Type Provider Sample - Updated Functionality

We're pleased to announce that a new type provider sample has been added to the F# 3.0 Sample Pack: the Microsoft Dynamics CRM 2011 type provider. For those in a hurry, you can watch a short screencast here(a longer version is in the works).

This sample uses the F# 3.0 Type Provider mechanism to provide scalable access to strongly typed CRM entities without the need for code generation. You can read more about the various kinds of Type Providers here and check out the other samples in the samples pack. A technical report on F# type providers called Strongly-Typed Language Support for Internet-Scale Information Sourcesis available from Microsoft Research.

A default install of Microsoft Dynamics CRM 2011 contains a wealth of schematized data tables pertaining to the customer relations of a business. Additionally, the product suite allows the default data schema to be extended and heavily customised. This means Microsoft Dynamics CRM is frequently used to model the custom domain requirements of particular enterprises. From a developer perspective, the data can be accessed in a dynamic fashion using the CRM Organization Service with a QueryExpressionor FetchXml. Later versions of CRM introduced a LINQ provider over the QueryExpression which works effectively but requires a large amount of generated code in order to function. The problems caused by this generated code can be very significant for CRM programming teams, even to the point where schema changes are avoided because of the need to regenerate massive code files.

The vision we are pursuing with this work is that someone working with Microsoft Dynamic CRM data should experience the same immediate, simple, scalable and intuitive access to massive enterprise schemas as we have achieved with many other data sources. Wouldn't it be nice if the various entities in CRM were automatically at your fingertips in a strongly typed fashion, and didn't require large amounts of generated code? Wouldn't it be nice if changes in the data schema would automatically reflect into programs and data scripts, removing the possibility of runtime errors due to mismatched code and data schema? This, amongst other nice features, is what this F# 3.0 type provider gives you.

To get going with this sample, you will first need a fully functioning CRM deployment and access to the OrganizationService endpoint. We understand that many of you won't have this, so you can also watch the screencast linked above to see the type provider sample in action. (The following steps assume the client is on the same domain as the service; if this is not the case, please see later blog posts on static parameters to address this)

To get going with the sample

  1. You will need the Mircrosoft Identity Foundation in order to query the organization service (In Windows Server 2012 and Windows 8 this can be installed via "Add Windows Features")
  2. Install F# 3.0, either through an evaluation copy of Visual Studio 2012 or using the Free F# Tools for Visual Studio 2012 Web Express
  3. Download and unzip the latest HEAD copy of the F# 3.0 Sample Pack
  4. Go to SampleProviders\Samples.Xrm. Open and build Samples. Xrm.Provider.sln
  5. Create a new script referencing Samples.XrmProvider.dll

#r @"System.Runtime.Serializaation"
#r @"lib\Microsoft.Xrm.Sdk.dll"
#r @"bin\Debug\Samples.XrmProvider.dll"

open Samples.XrmProvider

let xrm =
    XrmDataProvider<"https://server/org/XRMServices/2011/Organization.svc">.GetDataContext()
let accounts = xrm.accountSet |> Seq.toList

Assuming everything has gone as intended, you will now have retrieved all the Account entities from the organization in just 2 lines of code! (Perhaps don't try this if you have millions of accounts..)

You can now use F# Query Expressionsto create LINQ queries over the data. The provider currently supports a subset of the LINQ query operations and a few of the F# specific query expression keywords, with more to come in future releases. More information on building queries will be detailed in later blog posts. Additionally, you can look at the test project for to get a feel for different query compositions.

let accounts =
    query { for a in xrm.accountSet do
            where (a.name.Contains "Contoso")
            select a } |> Seq.toList

Some cool things implemented by the new sample include:

  • Standard LINQ functionality including filtering, projections, sorting, distinct
  • Paging via Skip and Take
  • Opt-in nullable values on appropriate CRM attributes and support for F# Nullable operators
  • Entity relationships can be queried without having to use explicit joins or know which attributes to join on
  • Support for many-to-many relationships
  • Custom operators allow you to use CRM conditional operators such as In and Not In

Some limitations of the provider are as follows:

  • Many to many relationships to/from the same entity type are not implemented
  • Aggregation operations are not implemented
  • There are some restrictions with the way parents / children can be selected (more on this in later posts)
  • A connection to the organization service is required during compilation

Here is a screenshot using IntelliSense to explore an account entity.

We hope you enjoy the sample and learn a lot from it.