Пример #1
0
        private static void ParseMinMaxValues(AttributeMetadata attribute, MappingField result)
        {
            if (attribute is StringAttributeMetadata)
            {
                var attr = attribute as StringAttributeMetadata;

                result.MaxLength = attr.MaxLength ?? result.MaxLength;
            }

            if (attribute is MemoAttributeMetadata)
            {
                var attr = attribute as MemoAttributeMetadata;

                result.MaxLength = attr.MaxLength ?? result.MaxLength;
            }

            if (attribute is IntegerAttributeMetadata)
            {
                var attr = attribute as IntegerAttributeMetadata;

                result.Min = attr.MinValue ?? result.Min;
                result.Max = attr.MaxValue ?? result.Max;
            }

            if (attribute is DecimalAttributeMetadata)
            {
                var attr = attribute as DecimalAttributeMetadata;

                result.Min = attr.MinValue ?? result.Min;
                result.Max = attr.MaxValue ?? result.Max;
            }

            if (attribute is MoneyAttributeMetadata)
            {
                var attr = attribute as MoneyAttributeMetadata;

                result.Min = attr.MinValue != null ? (decimal)attr.MinValue.Value : result.Min;
                result.Max = attr.MaxValue != null ? (decimal)attr.MaxValue.Value : result.Max;
            }

            if (attribute is DoubleAttributeMetadata)
            {
                var attr = attribute as DoubleAttributeMetadata;

                result.Min = attr.MinValue != null ? (decimal)attr.MinValue.Value : result.Min;
                result.Max = attr.MaxValue != null ? (decimal)attr.MaxValue.Value : result.Max;
            }
        }
Пример #2
0
        private static void ParseDateTime(AttributeMetadata attribute, MappingField result)
        {
            var metadata  = attribute as DateTimeAttributeMetadata;
            var behaviour = metadata?.DateTimeBehavior?.Value;

            if (metadata != null)
            {
                if (result.FieldType == AttributeTypeCode.DateTime &&
                    !string.IsNullOrEmpty(behaviour))
                {
                    try
                    {
                        result.DateTimeBehavior = (DateTimeBehavior)Enum.Parse(typeof(DateTimeBehavior), behaviour);
                    }
                    catch
                    {
                        // ignored
                    }
                }
            }
        }
        private static void AddImages(List <MappingField> fields)
        {
            var fieldsIterator = fields.Where(e => e.Attribute.IsImage).ToArray();

            foreach (var image in fieldsIterator)
            {
                image.TargetTypeForCrmSvcUtil = "byte[]";

                var imageTimestamp =
                    new MappingField
                {
                    Attribute =
                        new CrmPropertyAttribute
                    {
                        IsLookup                = false,
                        LogicalName             = $"{image.LogicalName}_timestamp",
                        IsEntityReferenceHelper = false
                    },
                    SchemaName      = $"{image.SchemaName}_Timestamp",
                    DisplayName     = $"{image.DisplayName}_Timestamp",
                    HybridName      = $"{image.HybridName}_Timestamp",
                    Label           = $"{image.Label}_Timestamp",
                    LocalizedLabels = image
                                      .LocalizedLabels.Select(
                        e =>
                    {
                        var copy   = e.Copy();
                        copy.Label = $"{copy.Label}_Timestamp";
                        return(copy);
                    }).ToArray(),
                    TargetTypeForCrmSvcUtil = "long?",
                    FieldType        = AttributeTypeCode.BigInt,
                    IsValidForRead   = true,
                    IsValidForCreate = false,
                    IsValidForUpdate = false,
                    Description      = " ",                        // CrmSvcUtil provides an empty description for this EntityImage_TimeStamp
                    GetMethod        = ""
                };
                SafeAddField(fields, imageTimestamp);

                var imageUrl =
                    new MappingField
                {
                    Attribute =
                        new CrmPropertyAttribute
                    {
                        IsLookup                = false,
                        LogicalName             = $"{image.LogicalName}_url",
                        IsEntityReferenceHelper = false
                    },
                    SchemaName      = $"{image.SchemaName}_URL",
                    DisplayName     = $"{image.DisplayName}_URL",
                    HybridName      = $"{image.HybridName}_URL",
                    Label           = $"{image.Label}_URL",
                    LocalizedLabels = image
                                      .LocalizedLabels.Select(
                        e =>
                    {
                        var copy   = e.Copy();
                        copy.Label = $"{copy.Label}_URL";
                        return(copy);
                    }).ToArray(),
                    TargetTypeForCrmSvcUtil = "string",
                    FieldType        = AttributeTypeCode.String,
                    IsValidForRead   = true,
                    IsValidForCreate = false,
                    IsValidForUpdate = false,
                    Description      = " ",                        // CrmSvcUtil provides an empty description for this EntityImage_URL
                    GetMethod        = ""
                };
                SafeAddField(fields, imageUrl);
            }
        }
        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);
        }
Пример #5
0
        private static string GetTargetType(MappingField field)
        {
            if (field.IsPrimaryKey)
            {
                return("Guid?");
            }

            switch (field.FieldType)
            {
            case AttributeTypeCode.Picklist:
                return("OptionSetValue");

            case AttributeTypeCode.BigInt:
                return("long?");

            case AttributeTypeCode.Integer:
                return("int?");

            case AttributeTypeCode.Boolean:
                return("bool?");

            case AttributeTypeCode.DateTime:
                return("DateTime?");

            case AttributeTypeCode.Decimal:
                return("decimal?");

            case AttributeTypeCode.Money:
                return("Money");

            case AttributeTypeCode.Double:
                return("double?");

            case AttributeTypeCode.Uniqueidentifier:
                return("Guid?");

            case AttributeTypeCode.Lookup:
            case AttributeTypeCode.Owner:
            case AttributeTypeCode.Customer:
                return("EntityReference");

            case AttributeTypeCode.State:
                return(field.Entity.StateName + "?");

            case AttributeTypeCode.Status:
                return("OptionSetValue");

            case AttributeTypeCode.Memo:
            case AttributeTypeCode.Virtual:
            case AttributeTypeCode.EntityName:
            case AttributeTypeCode.String:
                return("string");

            case AttributeTypeCode.PartyList:
                return("ActivityParty[]");

            case AttributeTypeCode.ManagedProperty:
                return("BooleanManagedProperty");

            default:
                return("object");
            }
        }
Пример #6
0
        public static MappingField GetMappingField(AttributeMetadata attribute, MappingEntity entity,
                                                   MappingField result, bool isTitleCaseLogicalName)
        {
            result = result ?? new MappingField();

            result.Entity           = entity;
            result.MetadataId       = attribute.MetadataId;
            result.LogicalName      = attribute.LogicalName ?? result.LogicalName;
            result.AttributeOf      = attribute.AttributeOf ?? result.AttributeOf;
            result.IsValidForCreate = attribute.IsValidForCreate ?? result.IsValidForCreate;
            result.IsValidForRead   = attribute.IsValidForRead ?? result.IsValidForRead;
            result.IsValidForUpdate = attribute.IsValidForUpdate ?? result.IsValidForUpdate;

            if (attribute.AttributeType != null)
            {
                result.FieldType       = attribute.AttributeType.Value;
                result.IsActivityParty = attribute.AttributeType == AttributeTypeCode.PartyList;
                result.IsStateCode     = attribute.AttributeType == AttributeTypeCode.State;
            }

            result.DeprecatedVersion = attribute.DeprecatedVersion ?? result.DeprecatedVersion;

            if (attribute.DeprecatedVersion != null)
            {
                result.IsDeprecated = !string.IsNullOrWhiteSpace(attribute.DeprecatedVersion);
            }

            if (attribute is EnumAttributeMetadata || attribute is BooleanAttributeMetadata)
            {
                result.EnumData = MappingEnum.GetMappingEnum(attribute, result.EnumData, isTitleCaseLogicalName);
            }

            if (attribute is LookupAttributeMetadata lookup)
            {
                result.LookupData = new MappingLookup();

                if (lookup.Targets?.Length == 1)
                {
                    result.LookupData.LookupSingleType = lookup.Targets[0];
                }
            }

            ParseDateTime(attribute, result);
            ParseMinMaxValues(attribute, result);
            ParseImageValues(attribute, result);

            result.IsPrimaryKey = attribute.IsPrimaryId ?? result.IsPrimaryKey;

            if (attribute.SchemaName != null)
            {
                result.SchemaName = attribute.SchemaName ?? result.SchemaName;

                if (attribute.LogicalName != null)
                {
                    result.DisplayName = Naming.GetProperVariableName(attribute, isTitleCaseLogicalName);
                }

                result.PrivatePropertyName = Naming.GetEntityPropertyPrivateName(attribute.SchemaName);
            }

            result.HybridName = Naming.GetProperHybridFieldName(result.DisplayName, result.Attribute);

            if (attribute.Description?.UserLocalizedLabel != null)
            {
                result.Description = attribute.Description.UserLocalizedLabel.Label;
            }

            if (attribute.DisplayName != null)
            {
                if (attribute.DisplayName.LocalizedLabels != null)
                {
                    result.LocalizedLabels = attribute.DisplayName.LocalizedLabels
                                             .Select(label =>
                                                     new LocalizedLabelSerialisable
                    {
                        LanguageCode = label.LanguageCode,
                        Label        = label.Label
                    }).ToArray();
                }

                if (attribute.DisplayName.UserLocalizedLabel != null)
                {
                    result.Label = attribute.DisplayName.UserLocalizedLabel.Label;
                }
            }

            if (attribute.RequiredLevel != null)
            {
                result.IsRequired = attribute.RequiredLevel.Value == AttributeRequiredLevel.ApplicationRequired;
            }

            if (attribute.AttributeType != null)
            {
                result.Attribute =
                    new CrmPropertyAttribute
                {
                    LogicalName = attribute.LogicalName,
                    IsLookup    = attribute.AttributeType == AttributeTypeCode.Lookup ||
                                  attribute.AttributeType == AttributeTypeCode.Owner ||
                                  attribute.AttributeType == AttributeTypeCode.Customer,
                    IsImage = attribute is ImageAttributeMetadata
                };
                result.Attribute.IsMultiTyped = result.Attribute.IsLookup && result.LookupData?.LookupSingleType.IsEmpty() == true;
            }

            result.TargetTypeForCrmSvcUtil = GetTargetType(result);
            result.FieldTypeString         = result.TargetTypeForCrmSvcUtil;

            return(result);
        }