private void GenerateLists() { if (AttributeMetadataCache[LogicalName] == null) { throw new Exception("Failed to load metadata related to this entity."); } // choose non-primary attributes, and ones that don't represent others (like names of OptionSetValues) // sort by IsSelected, and then by name -- bubbles the selected to the top var attributes = from attributeQ in AttributeMetadataCache[LogicalName].Attributes where (!attributeQ.IsPrimaryId.HasValue || !attributeQ.IsPrimaryId.Value) && string.IsNullOrEmpty(attributeQ.AttributeOf) orderby EntityDataFilter.Attributes == null || EntityDataFilter.Attributes.Contains(attributeQ.LogicalName) descending, attributeQ.LogicalName select attributeQ; // if no filter, select all FieldsSelectAll = EntityDataFilter.Attributes != null && EntityDataFilter.Attributes.Length == attributes.Count(); ReadOnlySelectAll = EntityDataFilter.ReadOnly != null && EntityDataFilter.ReadOnly.Length == attributes.Count(); ClearFlagSelectAll = EntityDataFilter.ClearFlag != null && EntityDataFilter.ClearFlag.Length == attributes.Count(); foreach (var attribute in attributes) { var attributeAsync = attribute; Dispatcher.Invoke(() => { Fields.Add(new FieldGridRow { IsSelected = EntityDataFilter.Attributes?.Contains(attributeAsync.LogicalName) == true, Name = attributeAsync.LogicalName, DisplayName = attributeAsync.DisplayName?.UserLocalizedLabel == null || !Settings.UseDisplayNames ? Naming.GetProperVariableName(attributeAsync, Settings.TitleCaseLogicalNames) : Naming.Clean(attributeAsync.DisplayName.UserLocalizedLabel.Label), Rename = EntityDataFilter.AttributeRenames?.FirstNotNullOrEmpty(attributeAsync.LogicalName), Language = EntityDataFilter.AttributeLanguages?.FirstNotNullOrEmpty(attributeAsync.LogicalName), IsReadOnly = EntityDataFilter.ReadOnly?.Contains(attributeAsync.LogicalName) == true || (attributeAsync.IsValidForCreate != true && attributeAsync.IsValidForUpdate != true), IsReadOnlyEnabled = attributeAsync.IsValidForCreate == true || attributeAsync.IsValidForUpdate == true, IsClearFlag = EntityDataFilter.ClearFlag?.Contains(attributeAsync.LogicalName) == true }); }); } var relations1N = from relation1nQ in AttributeMetadataCache[LogicalName].OneToManyRelationships orderby EntityDataFilter.OneToN == null || EntityDataFilter.OneToN.Contains(relation1nQ.SchemaName) descending, relation1nQ.ReferencingEntity, relation1nQ.ReferencingAttribute select relation1nQ; // if no filter, select all Relations1NSelectAll = EntityDataFilter.OneToN != null && EntityDataFilter.OneToN.Length == relations1N.Count(); foreach (var relation1n in relations1N) { var relation1nAsync = relation1n; Dispatcher.Invoke(() => { var row = new Relations1NGridRow { IsSelected = EntityDataFilter.OneToN == null || EntityDataFilter.OneToN.Contains(relation1nAsync.SchemaName), Name = relation1nAsync.SchemaName, ToEntity = relation1nAsync.ReferencingEntity ?? "", ToField = relation1nAsync.ReferencingAttribute ?? "", Rename = EntityDataFilter.OneToNRenames?.FirstNotNullOrEmpty(relation1nAsync.SchemaName), IsReadOnlyEnabled = true, IsReadOnly = EntityDataFilter.OneToNReadOnly != null && EntityDataFilter.OneToNReadOnly.ContainsKey( relation1nAsync.SchemaName) && EntityDataFilter.OneToNReadOnly[relation1nAsync.SchemaName] }; Relations1N.Add(row); }); } var relationsN1 = from relationN1Q in AttributeMetadataCache[LogicalName].ManyToOneRelationships orderby EntityDataFilter.NToOne == null || EntityDataFilter.NToOne.Contains(relationN1Q.SchemaName) descending, relationN1Q.ReferencedEntity, relationN1Q.ReferencingAttribute select relationN1Q; // if no filter, select all RelationsN1SelectAll = EntityDataFilter.NToOne != null && EntityDataFilter.NToOne.Length == relationsN1.Count(); foreach (var relationN1 in relationsN1) { var relationN1Async = relationN1; Dispatcher.Invoke(() => { var row = new RelationsN1GridRow { IsSelected = EntityDataFilter.NToOne == null || EntityDataFilter.NToOne.Contains(relationN1Async.SchemaName), Name = relationN1Async.SchemaName, ToEntity = relationN1Async.ReferencedEntity ?? "", FromField = relationN1Async.ReferencingAttribute ?? "", Rename = EntityDataFilter.NToOneRenames? .FirstNotNullOrEmpty(relationN1Async.SchemaName), IsFlatten = EntityDataFilter.NToOneFlatten != null && EntityDataFilter.NToOneFlatten.ContainsKey( relationN1Async.SchemaName) && EntityDataFilter.NToOneFlatten[relationN1Async.SchemaName], IsReadOnlyEnabled = true, IsReadOnly = EntityDataFilter.NToOneReadOnly != null && EntityDataFilter.NToOneReadOnly.ContainsKey( relationN1Async.SchemaName) && EntityDataFilter.NToOneReadOnly[relationN1Async.SchemaName] }; RelationsN1.Add(row); }); } var relationsNN = from relationNNQ in AttributeMetadataCache[LogicalName].ManyToManyRelationships orderby EntityDataFilter.NToN == null || EntityDataFilter.NToN.Contains(relationNNQ.SchemaName) descending, (relationNNQ.Entity1LogicalName == LogicalName) ? relationNNQ.Entity2LogicalName : (relationNNQ.Entity1LogicalName ?? ""), relationNNQ.IntersectEntityName select relationNNQ; // if no filter, select all RelationsNNSelectAll = EntityDataFilter.NToN != null && EntityDataFilter.NToN.Length == relationsNN.Count(); foreach (var relationNN in relationsNN) { var relationNNAsync = relationNN; Dispatcher.Invoke(() => { var row = new RelationsNNGridRow { IsSelected = EntityDataFilter.NToN == null || EntityDataFilter.NToN.Contains(relationNNAsync.SchemaName), Name = relationNNAsync.SchemaName, ToEntity = relationNNAsync.Entity1LogicalName == LogicalName ? relationNNAsync.Entity2LogicalName : (relationNNAsync.Entity1LogicalName ?? ""), IntersectEntity = relationNNAsync.IntersectEntityName ?? "", Rename = EntityDataFilter.NToNRenames?.FirstNotNullOrEmpty(relationNNAsync.SchemaName), IsReadOnlyEnabled = true, IsReadOnly = EntityDataFilter.NToNReadOnly != null && EntityDataFilter.NToNReadOnly.ContainsKey( relationNNAsync.SchemaName) && EntityDataFilter.NToNReadOnly[relationNNAsync.SchemaName] }; RelationsNN.Add(row); }); } }