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"
#load @"DG.Delegate.HowToDaxif.DataManagement.Helper.fsx"
module cfg = DG.Delegate.HowToDaxif.Config
module hlp = DG.Delegate.HowToDaxif.DataManagement.Helper
(** 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.Messages
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>
let account name =
let attribs = new AttributeCollection()
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 (hlp.rand())) // Slower
|> Seq.map(fun a ->
CrmData.CRUD.create (hlp.proxy()) a (new ParameterCollection()))
|> Seq.iter(printfn "%A") // printfn isn't thread-safe
Array.init 1000 (fun _ -> account (hlp.rand())) // Faster with parallelism
|> Array.Parallel.map(fun a ->
CrmData.CRUD.create (hlp.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
(hlp.proxy()) target.Metadata.Account.``(LogicalName)`` query
// 2) Delete all entities from query (with ExecuteMultiple and parallelism)
accounts ()
|> hlp.Seq.split (10*1000)
|> Seq.iter(fun xs ->
printfn "- Chunks of 10.000"
xs
|> Array.Parallel.map(fun e -> CRUD.deleteReq e.LogicalName e.Id)
|> Array.toSeq
// ExecuteMultiple - Run-time limitations:
// https://msdn.microsoft.com/en-us/library/jj863631.aspx#limitations
|> hlp.Seq.split 1000
|> Seq.toArray
|> Array.Parallel.map (fun dreqs ->
let orc = new OrganizationRequestCollection()
dreqs // OrganizationRequestCollection is not thread-safe
|> Array.iter (fun x -> orc.Add(x))
let emreqs = new ExecuteMultipleRequest()
emreqs.Settings <- new ExecuteMultipleSettings()
emreqs.Settings.ContinueOnError <- true
emreqs.Settings.ReturnResponses <- true
emreqs.Requests <- orc
emreqs, dreqs)
|> Array.Parallel.map (fun (emreqs, dreqs) ->
try
(hlp.proxy().Execute(emreqs) :?> ExecuteMultipleResponse, dreqs) |> Some
with ex ->
Console.Error.WriteLine(sprintf "* Proxy execute: %s" ex.Message); None)
|> Array.Parallel.choose (id)
|> Array.Parallel.iter (fun (emresps, _) ->
emresps.Responses
|> Seq.toArray
|> Array.Parallel.iter(fun kv ->
match kv.Fault with
| null -> ()
| fault ->
Console.Error.WriteLine(
sprintf " --Execute multiple: %s" fault.Message))))
// 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