public static MappingRelationshipMN Parse(ManyToManyRelationshipMetadata rel, MappingRelationshipMN relationshipManyToMany, string thisEntityLogicalName) { relationshipManyToMany = relationshipManyToMany ?? new MappingRelationshipMN(); if (rel.Entity1LogicalName != null) { if (rel.Entity1LogicalName == thisEntityLogicalName) { relationshipManyToMany.Attribute = relationshipManyToMany.Attribute ?? new CrmRelationshipAttribute(); relationshipManyToMany.Attribute.FromEntity = rel.Entity1LogicalName ?? relationshipManyToMany.Attribute.FromEntity; relationshipManyToMany.Attribute.FromKey = rel.Entity1IntersectAttribute ?? relationshipManyToMany.Attribute.FromKey; relationshipManyToMany.Attribute.ToEntity = rel.Entity2LogicalName ?? relationshipManyToMany.Attribute.ToEntity; relationshipManyToMany.Attribute.ToKey = rel.Entity2IntersectAttribute ?? relationshipManyToMany.Attribute.ToKey; } else { relationshipManyToMany.Attribute = relationshipManyToMany.Attribute ?? new CrmRelationshipAttribute(); relationshipManyToMany.Attribute.ToEntity = rel.Entity1LogicalName ?? relationshipManyToMany.Attribute.ToEntity; relationshipManyToMany.Attribute.ToKey = rel.Entity1IntersectAttribute ?? relationshipManyToMany.Attribute.ToKey; relationshipManyToMany.Attribute.FromEntity = rel.Entity2LogicalName ?? relationshipManyToMany.Attribute.FromEntity; relationshipManyToMany.Attribute.FromKey = rel.Entity2IntersectAttribute ?? relationshipManyToMany.Attribute.FromKey; } relationshipManyToMany.Attribute.IntersectingEntity = rel.IntersectEntityName ?? relationshipManyToMany.Attribute.IntersectingEntity; } relationshipManyToMany.EntityRole = "null"; if (rel.SchemaName != null) { relationshipManyToMany.SchemaName = rel.SchemaName; relationshipManyToMany.DisplayName = rel.SchemaName; relationshipManyToMany.HybridName = Naming.GetProperVariableName(rel.SchemaName, false) + "_NN"; relationshipManyToMany.PrivateName = "_nn" + Naming.GetEntityPropertyPrivateName(rel.SchemaName); } if (rel.Entity1LogicalName != null && rel.Entity2LogicalName != null && rel.Entity1LogicalName == rel.Entity2LogicalName && rel.Entity1LogicalName == thisEntityLogicalName) { relationshipManyToMany.DisplayName = "Referenced_" + relationshipManyToMany.DisplayName; relationshipManyToMany.EntityRole = "Microsoft.Xrm.Sdk.EntityRole.Referenced"; relationshipManyToMany.IsSelfReferenced = true; } if (relationshipManyToMany.DisplayName == thisEntityLogicalName) { relationshipManyToMany.DisplayName += "1"; // this is what CrmSvcUtil does } relationshipManyToMany.ForeignKey = Naming.GetProperVariableName(relationshipManyToMany.Attribute.ToKey, false); relationshipManyToMany.Type = relationshipManyToMany.Attribute.ToEntity; relationshipManyToMany.MetadataId = rel.MetadataId; return(relationshipManyToMany); }
internal static MappingEntity GetMappingEntity(EntityMetadata entityMetadata, string serverStamp, MappingEntity entity, bool isTitleCaseLogicalName) { entity = entity ?? new MappingEntity(); entity.MetadataId = entityMetadata.MetadataId; entity.ServerStamp = serverStamp; entity.Attribute = entity.Attribute ?? new CrmEntityAttribute(); entity.TypeCode = entityMetadata.ObjectTypeCode ?? entity.TypeCode; entity.Attribute.LogicalName = entityMetadata.LogicalName ?? entity.Attribute.LogicalName; entity.IsIntersect = (entityMetadata.IsIntersect ?? entity.IsIntersect); entity.Attribute.PrimaryKey = entityMetadata.PrimaryIdAttribute ?? entity.Attribute.PrimaryKey; if (entityMetadata.DisplayName?.UserLocalizedLabel != null) { entity.Label = entityMetadata.DisplayName.UserLocalizedLabel.Label; } if (entityMetadata.SchemaName != null) { entity.DisplayName = Naming.GetProperEntityName(entityMetadata.SchemaName); entity.SchemaName = entityMetadata.SchemaName; if (entityMetadata.LogicalName != null) { entity.HybridName = Naming.GetProperHybridName(entityMetadata.SchemaName, entityMetadata.LogicalName); } } entity.StateName = entity.HybridName + "State"; if (entityMetadata.Description?.UserLocalizedLabel != null) { entity.Description = entityMetadata.Description.UserLocalizedLabel.Label; } var fields = (entity.Fields ?? new MappingField[0]).ToList(); ////if (entityMetadata.Attributes != null) ////{ var validFields = entityMetadata.Attributes .Where(a => a.AttributeOf == null || a is ImageAttributeMetadata).ToArray(); foreach (var field in validFields) { var existingField = fields.FirstOrDefault(fieldQ => fieldQ.MetadataId == field.MetadataId); // if it exists, remove it from the list if (existingField != null) { fields.RemoveAll(fieldQ => fieldQ.MetadataId == field.MetadataId); } // update/create and add to list fields.Add(MappingField.GetMappingField(field, entity, existingField, isTitleCaseLogicalName)); } fields.ForEach( f => { if (f.DisplayName == entity.DisplayName) { f.DisplayName += "1"; } if (f.HybridName == entity.HybridName) { f.HybridName += "1"; } }); AddImages(fields); AddLookupFields(fields); entity.Fields = fields.ToArray(); // get the states enum from the metadata entity.States = entityMetadata.Attributes .Where(a => a is StateAttributeMetadata && a.AttributeOf == null) .Select(a => MappingEnum .GetMappingEnum(a as EnumAttributeMetadata, null, isTitleCaseLogicalName)) .FirstOrDefault() ?? entity.States; // get all optionsets from the metadata var newEnums = entityMetadata.Attributes .Where(a => (a is EnumAttributeMetadata || a is BooleanAttributeMetadata) && a.AttributeOf == null); // if there was never any enums previously, then just take the ones sent if (entity.Enums == null) { entity.Enums = newEnums .Select(newEnum => MappingEnum.GetMappingEnum(newEnum, null, isTitleCaseLogicalName)) .ToArray(); } else { var existingEnums = entity.Enums.ToList(); // else, update the changed ones newEnums.AsParallel() .ForAll(newEnum => { // has this enum been updated? var existingEnum = existingEnums .Find(existingEnumQ => existingEnumQ.MetadataId == newEnum.MetadataId); if (existingEnum != null) { // update it here entity.Enums[existingEnums.IndexOf(existingEnum)] = MappingEnum.GetMappingEnum(newEnum, existingEnum, isTitleCaseLogicalName); } else { // add new existingEnums.Add(MappingEnum.GetMappingEnum(newEnum, null, isTitleCaseLogicalName)); } }); entity.Enums = existingEnums.ToArray(); } ////} entity.PrimaryKey = entity.Fields.FirstOrDefault(f => f.Attribute.LogicalName == entity.Attribute.PrimaryKey); entity.PrimaryKeyProperty = entity.PrimaryKey?.DisplayName; entity.PrimaryNameAttribute = entityMetadata.PrimaryNameAttribute ?? entity.PrimaryNameAttribute; if (entityMetadata.Keys?.Any(e => e.KeyAttributes?.Any() == true) == true) { entity.AlternateKeys = entityMetadata.Keys.SelectMany(e => e.KeyAttributes).ToArray(); } if (entityMetadata.OneToManyRelationships != null) { MappingRelationship1N.UpdateCache(entityMetadata.OneToManyRelationships.ToList(), entity, entity.Fields); } if (entityMetadata.OneToManyRelationships != null) { MappingRelationshipN1.UpdateCache(entityMetadata.ManyToOneRelationships.ToList(), entity, entity.Fields); } if (entityMetadata.OneToManyRelationships != null) { MappingRelationshipMN.UpdateCache(entityMetadata.ManyToManyRelationships.ToList(), entity, entity.LogicalName); // add a clone for self-referenced relation var relationshipsManyToMany = entity.RelationshipsManyToMany.ToList(); var selfReferenced = relationshipsManyToMany.Where(r => r.IsSelfReferenced).ToList(); foreach (var referenced in selfReferenced) { if (relationshipsManyToMany.All(rel => rel.DisplayName != "Referencing" + Naming.GetProperVariableName(referenced.SchemaName, false))) { var referencing = (MappingRelationshipMN)referenced.Clone(); referencing.DisplayName = "Referencing" + Naming.GetProperVariableName(referenced.SchemaName, false); referencing.EntityRole = "Microsoft.Xrm.Sdk.EntityRole.Referencing"; relationshipsManyToMany.Add(referencing); } } entity.RelationshipsManyToMany = relationshipsManyToMany.OrderBy(r => r.DisplayName).ToArray(); } entity.FriendlyName = Naming.Clean(string.IsNullOrEmpty(entity.Label) ? Naming.Clean(entity.HybridName) : Naming.Clean(entity.Label)); // generate attribute friendly names and detect duplicates entity.Fields.AsParallel() .ForAll(field => { var cleanFieldName = Naming.Clean( string.IsNullOrEmpty(field.Label) ? Naming.Clean(field.DisplayName) : Naming.Clean(field.Label)) + (field == entity.PrimaryKey ? "Id" : ""); var isDuplicateName = entity.Fields .Count(fieldQ => Naming.Clean( string.IsNullOrEmpty(fieldQ.Label) ? Naming.Clean(fieldQ.DisplayName) : Naming.Clean(fieldQ.Label)) == cleanFieldName) > 1; isDuplicateName = isDuplicateName || cleanFieldName == "Attributes" || cleanFieldName == entity.FriendlyName || cleanFieldName == "LogicalName" || cleanFieldName == "EntityLogicalName" || cleanFieldName == "SchemaName" || cleanFieldName == "DisplayName" || cleanFieldName == "EntityTypeCode"; field.FriendlyName = cleanFieldName + (isDuplicateName ? "_" + field.DisplayName : ""); }); // generate enum friendly names entity.Enums.AsParallel() .ForAll(enm => { var attribute = entity.Fields.FirstOrDefault(field => field.LogicalName == enm.LogicalName); enm.FriendlyName = attribute == null ? enm.DisplayName : attribute.FriendlyName; }); return(entity); }