Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
(**
Delete entities with help of the XrmTypeProvider
================================================
Libraries
---------
Config information *)
#load @"DG.Delegate.HowToDaxif.Config.fsx"
module cfg = DG.Delegate.HowToDaxif.Config
(** Open libraries for use *)
#r @"System.ServiceModel"
#r @"System.Runtime.Serialization"
(** Open libraries for use *)
open System
open System.ServiceModel
open System.Runtime.Serialization
open Microsoft.Xrm.Sdk
open Microsoft.Xrm.Sdk.Client
open Microsoft.Xrm.Sdk.Query
open DG.Daxif
open DG.Daxif.HelperModules.Common
open DG.Daxif.HelperModules.Common.CrmData
open DG.Daxif.Modules
(**
DAXIF# operations
-----------------
Delete entities by using CrmData.CRUD module and the XrmTypeProvider *)
type target = XrmProvider<uri = cfg.wsdlDev, usr = cfg.usrDev, pwd = cfg.pwdDev>
// 0.a) Set up SDK Client
let auth = new AuthenticationCredentials()
do auth.ClientCredentials.UserName.UserName <- cfg.usrDev
do auth.ClientCredentials.UserName.Password <- cfg.pwdDev
let manager =
ServiceConfigurationFactory.CreateManagement<IOrganizationService>
(cfg.wsdlDev')
let token = manager.Authenticate(auth)
// 0.b) Define a SDK proxy function that is based on the Service Manager
// (for parallelism purpouses)
let proxy () =
let proxy' = new OrganizationServiceProxy(manager, token.SecurityTokenResponse)
do proxy'.EnableProxyTypes()
proxy'
// 0.c) Create a lot of accounts first
module Random =
let private r = new Random()
let bit () = r.Next(0,2).ToString()
let hex () = r.Next(0,16).ToString("X")
let number from ``to`` = r.Next(from,``to``).ToString()
let rand () = Random.number (1000*1000) (10*1000*1000) // 1.000.000 - 9.999.999
let account name =
let attribs = new KeyAttributeCollection()
attribs.Add(
key = target.Metadata.Account.Name,
value = name)
let entity = new Entity(entityName = target.Metadata.Account.``.LogicalName``)
entity.Attributes.AddRange(attribs)
entity
Seq.init 100 (fun _ -> account (rand())) // Slower
|> Seq.map(fun a -> CrmData.CRUD.create (proxy()) a (new ParameterCollection()))
|> Seq.iter(printfn "%A") // printfn isn't thread-safe
Array.init 1000 (fun _ -> account (rand())) // Faster with parallelism
|> Array.Parallel.map(fun a ->
CrmData.CRUD.create (proxy()) a (new ParameterCollection()))
|> Array.iter(fun guid -> Console.WriteLine(guid))
// 1) Get data based on query
let query = new QueryExpression(target.Metadata.Account.``.LogicalName``)
query.ColumnSet.AddColumn(target.Metadata.Account.AccountId)
let accounts () =
CrmData.CRUD.retrieveMultiple
(proxy()) target.Metadata.Account.``.LogicalName`` query
// 2) Delete all entities from query
module internal Seq = // Helper module to split sequence for parallel purposes
let split size source =
seq {
let r = ResizeArray()
for x in source do
r.Add(x)
if r.Count = size then
yield r.ToArray()
r.Clear()
if r.Count > 0 then yield r.ToArray()
}
accounts ()
|> Seq.split 1000
|> Seq.iter(fun xs ->
printfn "Chunks of 1000"
xs
|> Array.Parallel.map(fun a -> CRUD.delete (proxy()) a.LogicalName a.Id)
|> Array.iter(fun guid -> Console.WriteLine(guid))
)
// Remark: If steps 1 and 2 are done in the same evaluation (ALT+ENTER), you
// might get some System.Aggregation exception due to the sequence getting
// changed, therefore, just execute each step at the time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment