public static object Convert(object value, Dynamics365Entity entity, string attributeLogicalName, Dynamics365Connection connection, string targetEntityLogicalName)
        {
            object                   convertedValue    = default(object);
            EntityMetadata           entityMetadata    = entity.GetEntityMetadata(connection);
            AttributeMetadata        attributeMetadata = entityMetadata.Attributes.FirstOrDefault(findField => findField.LogicalName == attributeLogicalName);
            Dynamics365TypeConverter converter         = new Dynamics365TypeConverter(attributeMetadata, targetEntityLogicalName);
            Type destinationType = converter.Dynamics365Type;

            if (converter.CanConvertTo(destinationType))
            {
                try
                {
                    convertedValue = converter.ConvertTo(value, destinationType);
                }
                catch (Exception ex)
                {
                    throw new ArgumentException(string.Format("Cannot convert {0} '{1}' to {2}: {3}", attributeMetadata.DisplayName.UserLocalizedLabel.Label, value, destinationType.Name, ex.Message), ex);
                }
            }
            else
            {
                throw new ArgumentException(string.Format("Cannot convert {0} '{1}' to {2}.", attributeMetadata.DisplayName.UserLocalizedLabel.Label, value, destinationType.Name));
            }

            return(convertedValue);
        }
Exemple #2
0
        /// <summary>
        /// Creates a Dynamics365Field instance from the field's AttributeMetadata.
        /// </summary>
        /// <param name="attributeMetadata">The AttributeMetadata.</param>
        /// <returns>A Dynamics365Field.</returns>
        public static Dynamics365Field CreateFromMetadata(AttributeMetadata attributeMetadata, Dynamics365Connection connection)
        {
            Dynamics365Field         field     = null;
            Dynamics365TypeConverter converter = new Dynamics365TypeConverter(attributeMetadata);

            if (converter.CanConvertTo(converter.Dynamics365Type) && attributeMetadata.DisplayName.LocalizedLabels.Count > 0)
            {
                field = new Dynamics365Field()
                {
                    LogicalName       = attributeMetadata.LogicalName,
                    DisplayName       = attributeMetadata.DisplayName.UserLocalizedLabel.Label,
                    EntityLogicalName = attributeMetadata.EntityLogicalName,
                    IsPrimaryId       = (bool)attributeMetadata.IsPrimaryId,
                    CanCreate         = (bool)attributeMetadata.IsValidForCreate,
                    CanUpdate         = (bool)attributeMetadata.IsValidForUpdate,
                    Targets           = attributeMetadata is LookupAttributeMetadata ? ((LookupAttributeMetadata)attributeMetadata).Targets : default(string[])
                };

                // see https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/configure-activity-feeds
                if ((field.EntityLogicalName == "post" || field.EntityLogicalName == "postfollow") && attributeMetadata is LookupAttributeMetadata && field.Targets?.Length == 0)
                {
                    using (OrganizationServiceProxy proxy = connection.OrganizationServiceProxy)
                    {
                        ConnectionCache cache    = new ConnectionCache(connection);
                        string          cacheKey = string.Format("GetPostConfigurations");
                        string[]        targets  = (string[])cache[cacheKey];

                        if (targets == null)
                        {
                            const string ENTITY_NAME_LOGICAL_NAME = "msdyn_entityname";

                            FilterExpression filter = new FilterExpression();
                            filter.AddCondition("statecode", ConditionOperator.Equal, 0);
                            filter.AddCondition("statuscode", ConditionOperator.Equal, 1);

                            QueryExpression query = new QueryExpression()
                            {
                                EntityName = "msdyn_postconfig",
                                ColumnSet  = new ColumnSet(ENTITY_NAME_LOGICAL_NAME),
                                Criteria   = filter,
                            };

                            EntityCollection response = proxy.RetrieveMultiple(query);
                            field.Targets = new string[response.Entities.Count];

                            for (int entityIndex = 0; entityIndex < response.Entities.Count; entityIndex++)
                            {
                                field.Targets[entityIndex] = response.Entities[entityIndex].Attributes[ENTITY_NAME_LOGICAL_NAME].ToString();
                            }

                            cache[cacheKey] = field.Targets;
                        }
                    }
                }
            }

            return(field);
        }
        public override object GetValue(DataRow row, CancellationToken cancel, IProgress <ExecutionProgress> progress)
        {
            object value = base.GetValue(row, cancel, progress);
            string targetEntityLogicalName = default(string);

            if (((Dynamics365Field)DestinationField)?.Targets?.Length > 1)
            {
                if (targetMode == TargetMode.Fixed && TargetEntity != default(Dynamics365Entity))
                {
                    targetEntityLogicalName = TargetEntity.LogicalName;
                }
                else if (targetMode == TargetMode.Variable && TargetEntityField != default(DataTableField))
                {
                    targetEntityLogicalName = row[((DataTableField)targetEntityField).ColumnName].ToString();
                }
            }

            return(Dynamics365TypeConverter.Convert(value, ((Dynamics365RecordOperation)Parent).Entity, ((Dynamics365Field)DestinationField).LogicalName, ((Dynamics365RecordOperation)Parent).Connection, targetEntityLogicalName));
        }
        /// <summary>
        /// Appends rows to the specified data table from the specified EntityCollection.
        /// </summary>
        /// <param name="dataTable">The DataTable.</param>
        /// <param name="entities">The EntityCollection.</param>
        /// <param name="recordLimit">The record limit.</param>
        /// <returns>A DataTable with appended rows.</returns>
        protected DataTable AppendRows(DataTable dataTable, EntityCollection entities, int recordLimit)
        {
            Dictionary <string, EntityMetadata> metadata = new Dictionary <string, EntityMetadata>();

            foreach (DataColumn column in dataTable.Columns)
            {
                string entityLogicalName = column.ColumnName.Substring(0, column.ColumnName.IndexOf("."));

                if (!metadata.ContainsKey(entityLogicalName))
                {
                    metadata.Add(entityLogicalName, Dynamics365Entity.Create(entityLogicalName, (Dynamics365Connection)Parent).GetEntityMetadata((Dynamics365Connection)Parent));
                }
            }

            for (int recordIndex = 0; recordIndex < entities.Entities.Count && dataTable.Rows.Count < recordLimit; recordIndex++)
            {
                Entity  record = entities.Entities[recordIndex];
                DataRow row    = dataTable.NewRow();

                foreach (KeyValuePair <string, object> attribute in record.Attributes)
                {
                    string entityLogicalName    = record.LogicalName;
                    string attributeLogicalName = attribute.Key;
                    object attributeValue       = attribute.Value;

                    if (attribute.Value is AliasedValue)
                    {
                        AliasedValue aliasedValue = (AliasedValue)attribute.Value;
                        entityLogicalName    = aliasedValue.EntityLogicalName;
                        attributeLogicalName = aliasedValue.AttributeLogicalName;
                        attributeValue       = aliasedValue.Value;
                    }

                    string nativeColumnName = string.Format("{0}.{1}", entityLogicalName, attributeLogicalName);

                    if (DataTypes == DataTypes.Native)
                    {
                        if (dataTable.Columns.Contains(nativeColumnName))
                        {
                            row[nativeColumnName] = attributeValue;
                        }
                    }
                    else if (DataTypes == DataTypes.Neutral)
                    {
                        AttributeMetadata        attributeMetadata = metadata[entityLogicalName].Attributes.FirstOrDefault(findField => findField.LogicalName == attributeLogicalName);
                        Dynamics365TypeConverter converter         = new Dynamics365TypeConverter(attributeMetadata);

                        if (converter.Dynamics365Type == typeof(EntityReference) || converter.Dynamics365Type == typeof(EntityCollection))
                        {
                            if (LookupBehaviour == LookupBehaviour.Name || LookupBehaviour == LookupBehaviour.NameAndIdentifier || LookupBehaviour == LookupBehaviour.EntityAndNameAndIdentifier)
                            {
                                string nameColumn = string.Format("{0}.Name", nativeColumnName);

                                if (dataTable.Columns.Contains(nameColumn))
                                {
                                    if (converter.Dynamics365Type == typeof(EntityReference))
                                    {
                                        row[nameColumn] = ((EntityReference)attributeValue).Name;
                                    }
                                    else if (converter.Dynamics365Type == typeof(EntityCollection))
                                    {
                                        string names = string.Empty;

                                        foreach (Entity entity in ((EntityCollection)attributeValue).Entities)
                                        {
                                            EntityReference party = (EntityReference)entity["partyid"];
                                            names = names == string.Empty ? party.Name : string.Concat(names, PARTYLIST_DELIMITER, party.Name);
                                        }

                                        row[nameColumn] = names;
                                    }
                                }
                            }

                            if (LookupBehaviour == LookupBehaviour.Identifier || LookupBehaviour == LookupBehaviour.NameAndIdentifier || LookupBehaviour == LookupBehaviour.EntityAndNameAndIdentifier)
                            {
                                string identifierColumn = string.Format("{0}.Identifier", nativeColumnName);

                                if (dataTable.Columns.Contains(identifierColumn))
                                {
                                    if (converter.Dynamics365Type == typeof(EntityReference))
                                    {
                                        row[identifierColumn] = ((EntityReference)attributeValue).Id.ToString();
                                    }
                                    else if (converter.Dynamics365Type == typeof(EntityCollection))
                                    {
                                        string identifiers = string.Empty;

                                        foreach (Entity entity in ((EntityCollection)attributeValue).Entities)
                                        {
                                            EntityReference party = (EntityReference)entity["partyid"];
                                            identifiers = identifiers == string.Empty ? party.Id.ToString() : string.Concat(identifiers, PARTYLIST_DELIMITER, party.Id.ToString());
                                        }

                                        row[identifierColumn] = identifiers;
                                    }
                                }
                            }

                            if (LookupBehaviour == LookupBehaviour.Entity || LookupBehaviour == LookupBehaviour.EntityAndNameAndIdentifier)
                            {
                                string entityColumn = string.Format("{0}.Entity", nativeColumnName);

                                if (dataTable.Columns.Contains(entityColumn))
                                {
                                    if (converter.Dynamics365Type == typeof(EntityReference))
                                    {
                                        row[entityColumn] = ((EntityReference)attributeValue).LogicalName;
                                    }
                                    else if (converter.Dynamics365Type == typeof(EntityCollection))
                                    {
                                        string logicalNames = string.Empty;

                                        foreach (Entity entity in ((EntityCollection)attributeValue).Entities)
                                        {
                                            EntityReference party = (EntityReference)entity["partyid"];
                                            logicalNames = logicalNames == string.Empty ? party.LogicalName : string.Concat(logicalNames, PARTYLIST_DELIMITER, party.LogicalName);
                                        }

                                        row[entityColumn] = logicalNames;
                                    }
                                }
                            }
                        }
                        else if (converter.Dynamics365Type == typeof(OptionSetValue))
                        {
                            if (OptionSetBehaviour == OptionSetBehaviour.Name || OptionSetBehaviour == OptionSetBehaviour.NameAndCode)
                            {
                                string nameColumn = string.Format("{0}.Name", nativeColumnName);

                                if (dataTable.Columns.Contains(nameColumn))
                                {
                                    EnumAttributeMetadata enumMetadata   = (EnumAttributeMetadata)attributeMetadata;
                                    OptionMetadata        optionMetadata = enumMetadata.OptionSet.Options.FirstOrDefault(option => option.Value == ((OptionSetValue)attributeValue).Value);

                                    if (optionMetadata != default(OptionMetadata))
                                    {
                                        row[nameColumn] = optionMetadata.Label.UserLocalizedLabel.Label;
                                    }
                                }
                            }

                            if (OptionSetBehaviour == OptionSetBehaviour.Code || OptionSetBehaviour == OptionSetBehaviour.NameAndCode)
                            {
                                string codeColumn = string.Format("{0}.Code", nativeColumnName);

                                if (dataTable.Columns.Contains(codeColumn))
                                {
                                    row[codeColumn] = ((OptionSetValue)attributeValue).Value;
                                }
                            }
                        }
                        else if (converter.Dynamics365Type == typeof(OptionSetValueCollection))
                        {
                            if (OptionSetBehaviour == OptionSetBehaviour.Name || OptionSetBehaviour == OptionSetBehaviour.NameAndCode)
                            {
                                string nameColumn = string.Format("{0}.Name", nativeColumnName);

                                if (dataTable.Columns.Contains(nameColumn))
                                {
                                    List <string>            labels          = new List <string>();
                                    EnumAttributeMetadata    enumMetadata    = (EnumAttributeMetadata)attributeMetadata;
                                    OptionSetValueCollection optionSetValues = (OptionSetValueCollection)attributeValue;

                                    foreach (OptionSetValue optionSetValue in optionSetValues)
                                    {
                                        OptionMetadata optionMetadata = enumMetadata.OptionSet.Options.FirstOrDefault(option => option.Value == optionSetValue.Value);

                                        if (optionMetadata != default(OptionMetadata))
                                        {
                                            labels.Add(optionMetadata.Label.UserLocalizedLabel.Label);
                                        }
                                    }

                                    row[nameColumn] = string.Join(Dynamics365TypeConverter.MULTI_OPTION_SET_DELIMITER, labels.Select(label => label));
                                }
                            }

                            if (OptionSetBehaviour == OptionSetBehaviour.Code || OptionSetBehaviour == OptionSetBehaviour.NameAndCode)
                            {
                                string codeColumn = string.Format("{0}.Code", nativeColumnName);

                                if (dataTable.Columns.Contains(codeColumn))
                                {
                                    OptionSetValueCollection optionSetValues = (OptionSetValueCollection)attributeValue;
                                    row[codeColumn] = string.Join(Dynamics365TypeConverter.MULTI_OPTION_SET_DELIMITER, optionSetValues.Select(optionSet => optionSet.Value.ToString()));
                                }
                            }
                        }
                        else
                        {
                            if (dataTable.Columns.Contains(nativeColumnName))
                            {
                                row[nativeColumnName] = converter.ConvertFrom(null, null, attributeValue);
                            }
                        }
                    }
                }

                dataTable.Rows.Add(row);
            }

            return(dataTable);
        }
        /// <summary>
        /// Adds DataColumns to the specified dataTable for the specified field.
        /// </summary>
        /// <param name="dataTable">The data table.</param>
        /// <param name="field">The field.</param>
        /// <param name="attributeMetadata">The field attribute metadata.</param>
        protected void AddDataColumns(DataTable dataTable, Dynamics365Field field, AttributeMetadata attributeMetadata)
        {
            Dynamics365TypeConverter converter = new Dynamics365TypeConverter(attributeMetadata);

            if (DataTypes == DataTypes.Native)
            {
                DataColumn nativeColumn = new DataColumn()
                {
                    ColumnName = string.Format("{0}.{1}", field.EntityLogicalName, field.LogicalName),
                    Caption    = field.DisplayName,
                    DataType   = converter.Dynamics365Type
                };

                if (!dataTable.Columns.Contains(nativeColumn.ColumnName))
                {
                    dataTable.Columns.Add(nativeColumn);
                }
            }
            else if (DataTypes == DataTypes.Neutral)
            {
                if (converter.Dynamics365Type == typeof(EntityReference) || converter.Dynamics365Type == typeof(EntityCollection))
                {
                    if (LookupBehaviour == LookupBehaviour.Name || LookupBehaviour == LookupBehaviour.NameAndIdentifier || LookupBehaviour == LookupBehaviour.EntityAndNameAndIdentifier)
                    {
                        DataColumn nameColumn = new DataColumn()
                        {
                            ColumnName = string.Format("{0}.{1}{2}", field.EntityLogicalName, field.LogicalName, LookupBehaviour == LookupBehaviour.Name ? string.Empty : ".Name"),
                            Caption    = string.Format("{0}{1}", field.DisplayName, LookupBehaviour == LookupBehaviour.Name ? string.Empty : " (Name)"),
                            DataType   = typeof(string)
                        };

                        if (!dataTable.Columns.Contains(nameColumn.ColumnName)) // todo - fetch xml view on team entity caused duplication - investigate why
                        {
                            dataTable.Columns.Add(nameColumn);
                        }
                    }

                    if (LookupBehaviour == LookupBehaviour.Identifier || LookupBehaviour == LookupBehaviour.NameAndIdentifier || LookupBehaviour == LookupBehaviour.EntityAndNameAndIdentifier)
                    {
                        DataColumn identifierColumn = new DataColumn()
                        {
                            ColumnName = string.Format("{0}.{1}{2}", field.EntityLogicalName, field.LogicalName, LookupBehaviour == LookupBehaviour.Identifier ? string.Empty : ".Identifier"),
                            Caption    = string.Format("{0}{1}", field.DisplayName, LookupBehaviour == LookupBehaviour.Identifier ? string.Empty : " (Identifier)"),
                            DataType   = converter.Dynamics365Type == typeof(EntityReference) ? typeof(Guid) : typeof(string)
                        };
                        dataTable.Columns.Add(identifierColumn);
                    }

                    if (LookupBehaviour == LookupBehaviour.Entity || LookupBehaviour == LookupBehaviour.EntityAndIdentifier || LookupBehaviour == LookupBehaviour.EntityAndNameAndIdentifier)
                    {
                        DataColumn entityColumn = new DataColumn()
                        {
                            ColumnName = string.Format("{0}.{1}{2}", field.EntityLogicalName, field.LogicalName, LookupBehaviour == LookupBehaviour.Entity ? string.Empty : ".Entity"),
                            Caption    = string.Format("{0}{1}", field.DisplayName, LookupBehaviour == LookupBehaviour.Entity ? string.Empty : " (Entity)"),
                            DataType   = typeof(string)
                        };

                        if (!dataTable.Columns.Contains(entityColumn.ColumnName))
                        {
                            dataTable.Columns.Add(entityColumn);
                        }
                    }
                }
                else if (converter.Dynamics365Type == typeof(OptionSetValue) || converter.Dynamics365Type == typeof(OptionSetValueCollection))
                {
                    if (OptionSetBehaviour == OptionSetBehaviour.Name || OptionSetBehaviour == OptionSetBehaviour.NameAndCode)
                    {
                        DataColumn nameColumn = new DataColumn()
                        {
                            ColumnName = string.Format("{0}.{1}{2}", field.EntityLogicalName, field.LogicalName, OptionSetBehaviour == OptionSetBehaviour.Name ? string.Empty : ".Name"),
                            Caption    = string.Format("{0}{1}", field.DisplayName, OptionSetBehaviour == OptionSetBehaviour.Name ? string.Empty : " (Name)"),
                            DataType   = typeof(string)
                        };

                        if (!dataTable.Columns.Contains(nameColumn.ColumnName))
                        {
                            dataTable.Columns.Add(nameColumn);
                        }
                    }

                    if (OptionSetBehaviour == OptionSetBehaviour.Code || OptionSetBehaviour == OptionSetBehaviour.NameAndCode)
                    {
                        DataColumn codeColumn = new DataColumn()
                        {
                            ColumnName = string.Format("{0}.{1}{2}", field.EntityLogicalName, field.LogicalName, OptionSetBehaviour == OptionSetBehaviour.Code ? string.Empty : ".Code"),
                            Caption    = string.Format("{0}{1}", field.DisplayName, OptionSetBehaviour == OptionSetBehaviour.Code ? string.Empty : " (Code)"),
                            DataType   = converter.Dynamics365Type == typeof(OptionSetValue) ? typeof(int) : typeof(string)
                        };

                        if (!dataTable.Columns.Contains(codeColumn.ColumnName))
                        {
                            dataTable.Columns.Add(codeColumn);
                        }
                    }
                }
                else
                {
                    DataColumn neutralColumn = new DataColumn()
                    {
                        ColumnName = string.Format("{0}.{1}", field.EntityLogicalName, field.LogicalName),
                        Caption    = field.DisplayName,
                        DataType   = converter.NeutralType
                    };

                    if (!dataTable.Columns.Contains(neutralColumn.ColumnName))
                    {
                        dataTable.Columns.Add(neutralColumn);
                    }
                }
            }
        }