Code Snippet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#if INTERACTIVE
#r "System.Data.Services.Client"
#r "FSharp.Data.TypeProviders"
#endif
open System
open System.Net
open System.Data.Services.Client
open Microsoft.FSharp.Data
[<Literal>]
let url = @"https://demo.crm4.dynamics.com/XRMServices/2011/OrganizationData.svc/"
[<Literal>] // "%TMP%/odata/OrganizationData.csdl"
let csdl = __SOURCE_DIRECTORY__ + @"/odata/OrganizationData.csdl"
type Xrm =
TypeProviders.ODataService<
ServiceUri = url,
LocalSchemaFile = csdl,
ForceUpdate = false>
let ctx = Xrm.GetDataContext()
// To be used when writing JavaScript with OData
ctx.DataContext.SendingRequest.Add (
fun eventArgs -> printfn "-Url: %A" eventArgs.Request.RequestUri)
ctx.DataContext.SendingRequest.Add (
fun eventArgs -> printfn "-Query: %s" eventArgs.Request.RequestUri.Query)
// Remember to "pipe" to a Sequence, in order to evaluate the Linq Query:
query { for a in ctx.AccountSet do
where (a.AccountNumber = "42")
select (a.AccountNumber, a.AccountId)
skip 5
take 1}
|> Seq.map id
Code output:
Remark:
The reason LocalSchemaFile = csdl
and ForceUpdate =
false
are set to static values are because Microsoft still doesn’t allow
us to use OData from a server side context (we still need to login to CRM Online
with a browser that supports JavaScript). If anybody have a hint on how to
access the CSDL service from a .NET application, please write a comment below.
The point is that even though there is no data returned in the .NET application
from CRM Online, it doesn’t matter as we just want to use the queries (nicely
written in Linq with intellisense and type-safety) outputted from fun
eventArgs -> printfn "-Query: %s" eventArgs.Request.RequestUri.Query
for
our JavaScript code in combination with the official SDK.REST.js library:
1
2
3
4
5
6
7
8
9
SDK.REST.retrieveMultipleRecords(
"Account",
"$filter=AccountNumber eq '42'&$skip=5&$top=1&$select=AccountNumber,AccountId", // query
function (results) {
// Do stuff
},
errorHandler,
onCompleteHandler
);
The current way it’s done (and built on @deprecated technologies) is just not very handy (and has never been) as it requires to expand your current CRM tenant with a 3rd party managed solution: