Skip to content

Commit febde1c

Browse files
committed
Refactor EntityInfo to carry LogicalName; replace tuple targetEntitySets with EntityInfo[]
RawState now stores entities as an array; the nameMap is built later in interpretCrmData. XrmAttribute.targetEntitySets drops the option wrapper in favor of an empty array, and InterpretEntityMetadata uses Map.find instead of silently dropping unmapped lookup targets.
1 parent b2183a6 commit febde1c

9 files changed

Lines changed: 45 additions & 57 deletions

File tree

src/CreateTypeScript/CreateWebEntities.fs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ let getAttributeComment (attr: XrmAttribute) (options: OptionSet list option) =
6060
Comment.Attribute(
6161
attr.displayName,
6262
colType = attr.colType,
63-
?tes = attr.targetEntitySets,
63+
tes = attr.targetEntitySets,
6464
link = link,
6565
logicalName = logicalName
6666
)
@@ -223,25 +223,20 @@ let getFormattedVars (entity: XrmEntity) =
223223

224224
let getLookupNameVars (attrs: XrmAttribute list) =
225225
attrs
226-
|> List.choose (fun a ->
227-
match a.targetEntitySets with
228-
| None
229-
| Some [||] -> None
230-
| Some tes ->
231-
let unionType =
232-
tes
233-
|> Array.map (fun (n, _, _) -> TsType.Custom $"\"{n}\"")
234-
|> Array.toList
235-
|> TsType.Union
236-
237-
Some(
238-
Variable.Create(
239-
$"\"{valueInfix a.logicalName}@Microsoft.Dynamics.CRM.lookuplogicalname\"",
240-
unionType,
241-
Comment.Attribute(a.displayName, ?tes = a.targetEntitySets),
242-
optional = true
243-
)
244-
))
226+
|> List.filter (fun a -> a.specialType = SpecialType.EntityReference)
227+
|> List.map (fun a ->
228+
let unionType =
229+
a.targetEntitySets
230+
|> Array.map (fun e -> TsType.Custom $"\"{e.LogicalName}\"")
231+
|> Array.toList
232+
|> TsType.Union
233+
234+
Variable.Create(
235+
$"\"{valueInfix a.logicalName}@Microsoft.Dynamics.CRM.lookuplogicalname\"",
236+
unionType,
237+
Comment.Attribute(a.displayName, tes = a.targetEntitySets),
238+
optional = true
239+
))
245240
|> sortByName
246241

247242
let getScalarVars (filter: XrmAttribute -> bool) (entity: XrmEntity) =
@@ -294,9 +289,7 @@ let getIntersectEntities (nameMap: Map<string, EntityInfo>) (entity: XrmEntity)
294289
| [] -> []
295290
| rel :: _ ->
296291
[ rel.Entity1LogicalName; rel.Entity2LogicalName ]
297-
|> List.map (fun ln ->
298-
let eInfo = Map.find ln nameMap
299-
ln, eInfo.DisplayName)
292+
|> List.map (fun ln -> Map.find ln nameMap)
300293

301294
let getBlankEntityInterfaces (nameMap: Map<string, EntityInfo>) (entity: XrmEntity) =
302295
let comment =

src/Domain.fs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ type XdtRetrievalSettings = {
109109

110110
[<DataContract>]
111111
type EntityInfo = {
112+
[<field : DataMember(Name = "LogicalName")>]
113+
LogicalName: string
114+
112115
[<field : DataMember(Name = "SchemaName")>]
113116
SchemaName: string
114117

@@ -130,7 +133,7 @@ type RawState = {
130133
metadata: EntityMetadata[]
131134

132135
[<field : DataMember>]
133-
nameMap: Map<string, EntityInfo>
136+
info: EntityInfo[]
134137

135138
[<field : DataMember>]
136139
bpfData: Entity[]

src/Generation/DataRetrieval.fs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,19 @@ let connectToCrm xrmAuth =
1616
proxy
1717

1818
// Retrieve CRM entity name map
19-
let retrieveEntityNameMap mainProxy =
19+
let retrieveEntitiesInfo mainProxy =
2020
printf "Fetching entity names from CRM..."
2121

22-
let map =
22+
let arr =
2323
getAllEntityMetadataLight mainProxy
2424
|> Array.Parallel.map (fun m ->
25-
m.LogicalName,
26-
{ SchemaName = m.SchemaName
25+
{ LogicalName = m.LogicalName
26+
SchemaName = m.SchemaName
2727
EntitySetName = m.EntitySetName
2828
DisplayName = getLabel m.DisplayName })
29-
|> Map.ofArray
3029

3130
printfn "Done!"
32-
map
31+
arr
3332

3433
// Retrieve CRM entity metadata
3534
let retrieveEntityMetadata entities (mainProxy:IOrganizationService) =
@@ -57,8 +56,8 @@ let retrieveCrmVersion mainProxy =
5756

5857
/// Retrieve all the necessary CRM data
5958
let retrieveCrmData crmVersion entities (mainProxy:IOrganizationService) skipInactiveForms =
60-
let nameMap =
61-
retrieveEntityNameMap mainProxy
59+
let entitiesInfo =
60+
retrieveEntitiesInfo mainProxy
6261

6362
let rawEntityMetadata =
6463
retrieveEntityMetadata entities mainProxy
@@ -84,7 +83,7 @@ let retrieveCrmData crmVersion entities (mainProxy:IOrganizationService) skipIna
8483

8584
{
8685
RawState.metadata = rawEntityMetadata
87-
nameMap = nameMap
86+
info = entitiesInfo
8887
bpfData = bpfData
8988
formData = formData
9089
crmVersion = crmVersion

src/Generation/Setup.fs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ let intersectForms formDict formsToIntersect =
7171
let interpretCrmData (gSettings: XdtGenerationSettings) (rawState: RawState) =
7272
printf "Interpreting data..."
7373

74+
let nameMap = rawState.info |> Array.map (fun e -> e.LogicalName, e) |> Map.ofArray
75+
7476
let entityMetadata =
75-
rawState.metadata |> Array.Parallel.map (interpretEntity rawState.nameMap gSettings.labelMapping)
77+
rawState.metadata |> Array.Parallel.map (interpretEntity nameMap gSettings.labelMapping)
7678

7779
let bpfControls = interpretBpfs rawState.bpfData
7880

@@ -84,5 +86,5 @@ let interpretCrmData (gSettings: XdtGenerationSettings) (rawState: RawState) =
8486
bpfControls = bpfControls
8587
forms = forms
8688
outputDir = gSettings.out
87-
nameMap = rawState.nameMap
89+
nameMap = nameMap
8890
}

src/IntermediateRepresentation.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ type XrmAttribute = {
2626
logicalName: string
2727
varType: TsType
2828
specialType: SpecialType
29-
targetEntitySets: (string * string * string)[] option
29+
targetEntitySets: EntityInfo[]
3030
colType: XrmAttributeType
3131
readable: bool
3232
createable: bool

src/Interpretation/InterpretEntityMetadata.fs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,9 @@ let interpretAttribute (nameMap: Map<string, EntityInfo>) labelMapping (a: Attri
5757

5858
let targetEntitySets =
5959
match a with
60-
| :? LookupAttributeMetadata as lam ->
61-
lam.Targets
62-
|> Array.choose
63-
(fun k ->
64-
match Map.tryFind k nameMap with
65-
| None -> None
66-
| Some tes -> Some (k, tes.EntitySetName, tes.DisplayName)
67-
)
68-
|> Some
69-
| _ -> None
60+
| :? LookupAttributeMetadata as lam ->
61+
lam.Targets |> Array.map (fun k -> Map.find k nameMap)
62+
| _ -> [||]
7063

7164
let vType, sType = interpretNormalAttribute aType options
7265

src/Interpretation/InterpretFormXml.fs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,10 @@ let getTargetEntities (tes: string option) (a: XrmAttribute option) =
5151
| None, None -> "\"NoAttribute\""
5252
| None, Some a' ->
5353
match a'.targetEntitySets with
54-
| None -> if a.Value.specialType = Guid then "string" else "\"NoAttributeTargets\""
55-
| Some tes' ->
56-
let el = tes' |> Array.map (fun (l, _, _) -> l) |> Array.toList
57-
match el.IsEmpty with
58-
| true -> "\"NoTargets\""
59-
| false -> List.fold(fun acc e -> $"{acc} | \"{e}\"") ($"\"{el.Head}\"") el.Tail
54+
| [||] -> if a.Value.specialType = Guid then "string" else "\"NoAttributeTargets\""
55+
| tes' ->
56+
let el = tes' |> Array.map (fun e -> e.LogicalName) |> Array.toList
57+
List.fold(fun acc e -> $"{acc} | \"{e}\"") ($"\"{el.Head}\"") el.Tail
6058

6159
let getAttributeType = function
6260
| None -> TsType.Undefined
@@ -72,7 +70,7 @@ let getAttribute (enums:Map<string,TsType>) (entity: XrmEntity) (cField: Control
7270
let comment =
7371
match attribute with
7472
| None -> Comment.Basic cField.displayName
75-
| Some attr -> Comment.Attribute(attr.displayName, colType = attr.colType, ?tes = attr.targetEntitySets, link = getEnumLink entity.optionSets attr)
73+
| Some attr -> Comment.Attribute(attr.displayName, colType = attr.colType, tes = attr.targetEntitySets, link = getEnumLink entity.optionSets attr)
7674

7775
let attrType = getAttributeType attribute
7876

@@ -136,7 +134,7 @@ let getControl (enums:Map<string,TsType>) (entity: XrmEntity) (cField:ControlFi
136134
| None -> Comment.Basic cField.displayName
137135
| Some attr ->
138136
let label = if cField.displayName.Trim() <> attr.displayName.Trim() then cField.displayName else ""
139-
Comment.Attribute(attr.displayName, label = label, colType = attr.colType, ?tes = attr.targetEntitySets, link = getEnumLink entity.optionSets attr)
137+
Comment.Attribute(attr.displayName, label = label, colType = attr.colType, tes = attr.targetEntitySets, link = getEnumLink entity.optionSets attr)
140138

141139
let cType =
142140
match cField.controlClass with

src/TypeScript/Comment.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type Comment =
2020
if not (IsNullOrWhiteSpace setName) then yield $"Set Name: `{setName.Trim()}`"
2121
if defaultArg isIntersect false then yield "Intersect Table"
2222
match intersectEntities with
23-
| (ln1, dn1) :: (ln2, dn2) :: _ -> yield $"Intersects: {dn1} (`{ln1}`) ⟷ {dn2} (`{ln2}`)"
23+
| e1 :: e2 :: _ -> yield $"Intersects: {e1.DisplayName} (`{e1.LogicalName}`) ⟷ {e2.DisplayName} (`{e2.LogicalName}`)"
2424
| _ -> () ]
2525
|> Comment.Wrap
2626

@@ -36,7 +36,7 @@ type Comment =
3636
if not (IsNullOrWhiteSpace logicalName) then yield $"Lookup Field: `{logicalName.Trim()}`"
3737
if tes.Length > 0 then
3838
let maxDisplay = 5
39-
let shown = tes |> Array.truncate maxDisplay |> Array.map (fun (ln, _, dn) -> $"{dn} (`{ln}`)") |> String.concat " | "
39+
let shown = tes |> Array.truncate maxDisplay |> Array.map (fun e -> $"{e.DisplayName} (`{e.LogicalName}`)") |> String.concat " | "
4040
let formatted = if tes.Length <= maxDisplay then shown else $"{shown} | +{tes.Length - maxDisplay} more"
4141
yield $"Table: {formatted}"
4242
if not (IsNullOrWhiteSpace label) then yield $"Label: {label.Trim()}"

src/XdtData.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)