Microsoft Dynamics CRM Type Provider preview

by Pezi 30. December 2012 03:50

Are you tired of generating strongly typed classes with millions of lines of C# using crmsvcutil.exe that often crashes?  Fed up with having to re-generate the classes every time something in the schema changes?  Feeling restricted by the LINQ provider's limitations?  Ever wonder why you should need to know what attribute joins to what in your relationships to perform your joins? F# to the rescue!

I am working on a F# type provider than aims to solve a lot of these pains, and more besides!  This is just a sneak preview with what is to come, I have not released any of this yet.  First, here is an example of a rather silly but fairly complex query using the new type provider and the F# query syntax :

type XRM = Common.XRM.TypeProvider.XrmDataProvider<"http://something/Organization.svc">

let dc = XRM.GetDataContext()

type TestRecord = 
    { x : string; 
      y : int }

let test = { x = "John%"; y = 42 }

let q =
    query { for s in dc.new_squirrel do                            
            where (s.new_name <>% test.x || s.new_age = test.y)
            for f in s.``N:1 <- new_new_forest_new_squirrel`` do
            for o in f.``N:1 <- owner_new_forest`` do
            where (s.new_colour |=| [|"Pink";"Red"|])
            where (f.new_name = "Sherwood")
            where (o.name = "PEZI THE OWNER!")
            select (s, f.new_name, f, o) }

This example illustrates several cool features of the F# type provider ;

  • No code generation here - these "virtual" types are magically created on the fly by the compiler, using the organization service's metadata capabilities.  This provides full intellisense and only lazily loads the entity attributes and relationships on demand.  If your schema changes and breaks something, the code will not compile.
 
  • Where clauses can appear anywhere and be as complex as you want.  the only restriction is that only one entity type is used in each clause - this is because mixing OR logic between entities is impossible to translate into the underlying QueryExpression tree.
 
  • Relationships can be accessed via the SelectMany (for) syntax.  In this example Squirrel is the ultimate child and the code is traversing up the relationships through its parents (forest, and then owner).  Instead of needing to know or care about how these relationships are joined, this is handled for you in the magic.  Additionally, should you care, the intellisense will show you exactly what attribute is being joined to what.  It is also possible to start at a parent and traverse down the one-to-many relationships, as long as you don't branch off anywhere to more than one child as this is not supported in the underlying provider.
 
  • Custom operators!  F# lets you define your own operators. Currently I am supporting =% (like) <>% (not like)  |=| (in) and |<>| (not in) however it will be very easy to add more of these, or extensions to the relevant types to implement the wealth of other, sometimes rather exotic, XRM condition operators, of which almost all are not currently accessible from the existing LINQ provider, including in and not in. 
 
  • Projection expression - not only can you access attributes and perform any transformation, you may have noticed it allows you to select entire parent entities - you cannot do this in the current LINQ provider because the QueryExpression is only capable of returning an single entity type which has to be the ultimate child that you are selecting.  Any attributes from parents are kind of shoehorned into the result entity with aliases - more magic in the type provider enables you to select all the entities out as real CRM entities :) 
Joins are also still supported should you wish to use them explicitly for some reason.  At runtime, these "virtual" entities get "erased down" to a XrmEntity which is a thin wrapper inheriting from Entity - this means the resulting objects you can use everywhere like you normally would in your CRM code. 
 
Lots of stuff to come - paging, many LINQ execution methods, ordering, possibly even an auto conversion to fetchxml which will enable aggregate operations...

Tags:

F# | type providers

Comments (5) -

Nicolas Nowinski
Nicolas Nowinski
03/01/2013 04:16:24 #

Any chance you'll go ahead and share the Alpha code with some of us who might be interested in trying it out? Looks really cool.

pezi
pezi
04/01/2013 01:45:33 #

Hi! Thanks for your comment and interest.  Unfortunately right at the moment it's a bit of a mess as I am in the middle of some fairly extensive refactoring of it and there are several key things I need to add and fix before releasing anything - particularly the ability to pass an IOrganization service in a runtime. However, expect a release hopefully in the next few weeks, and it will be completely open source going forward - as is the F# way of things Smile

Tivas
Tivas
15/02/2013 19:45:12 #

Sounds very interresting. I'm working with CRM on a daily basis and would love to be able to do my code in F#.

looking very much forward to an open source release.

Big Up! and good job =)

--Tivas

pezi
pezi
15/02/2013 19:58:56 #

Hey! Thanks for your interest, this is a little delayed but you can expect to see it any day now!  Keep an eye on the Visual Studio F# team blog!

pezi
pezi
16/02/2013 20:11:23 #

The first release is now out!  Please see http://bit.ly/11L9q6i and http://bit.ly/15k3MXN

Pingbacks and trackbacks (6)+

Add comment

biuquote
  • Comment
  • Preview
Loading