public EntityProperties For(Type type) { var typeName = type.AssemblyQualifiedName; if (typeName == null) { throw new NullReferenceException("Assembly Qualifed Name for Type was null!"); } if (_dictionary.TryGetValue(typeName, out EntityProperties properties)) { return(properties); } properties = EntityProperties.Get(type); if (_dictionary.TryAdd(typeName, properties)) { return(properties); } if (_dictionary.TryGetValue(typeName, out properties)) { return(properties); } throw new Exception($"Could Not Add Type \"{typeName}\" to {GetType().Name}"); }
/// <summary> /// Adds the value to the entity only if the attribute is valid for the entity, and the condition is true /// </summary> private static void ConditionallyAddValue <T>(Entity entity, EntityProperties properties, string attributeName, T value, bool condition = true) { if (!condition || !properties.PropertiesByLogicalName.ContainsKey(attributeName)) { return; } if (value is DateTime) { entity[attributeName] = ((DateTime)(object)value).RemoveMilliseconds(); } else { entity[attributeName] = value; } }
public static EntityProperties Get(Type type) { var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance).ToDictionary(p => p.Name); var entity = new EntityProperties { EntityName = EntityHelper.GetEntityLogicalName(type), PropertiesByName = properties, PropertiesByLogicalName = properties.Values .Select(p => new { Key = p.GetAttributeLogicalName(false), Property = p }) .Where(p => p.Key != null) .GroupBy(k => k.Key, p => p.Property) .Select(g => new { g.Key, Property = g.FirstOrDefault() }) .ToDictionary(k => k.Key, p => p.Property), PropertiesByLowerCaseName = properties.GroupBy(v => v.Key.ToLower(), v => v.Value).ToDictionary(v => v.Key, v => v.ToList()) }; return(entity); }
/// <summary> /// AccountId/ParentContactId is auto-populated from the ParentCustomerId ( /// </summary> /// <typeparam name="T"></typeparam> /// <param name="entity">The entity.</param> /// <param name="properties">The properties.</param> private static void AutoPopulateContactFields <T>(T entity, EntityProperties properties) where T : Entity { if (entity.LogicalName != "contact") { return; } var customer = entity.GetAttributeValue <EntityReference>("parentcustomerid"); if (customer == null) { ConditionallyAddValue <EntityReference>(entity, properties, "parentcontactid", null, entity.GetAttributeValue <EntityReference>("parentcontactid") != null); ConditionallyAddValue <EntityReference>(entity, properties, "accountid", null, entity.GetAttributeValue <EntityReference>("accountid") != null); return; } var field = customer.LogicalName == "account" ? "accountid" : "parentcontactid"; var siblingField = field == "parentcontactid" ? "accountid" : "parentcontactid"; // Sibling is opposite ConditionallyAddValue(entity, properties, field, customer, !customer.Equals(entity.GetAttributeValue <EntityReference>(field))); ConditionallyAddValue <EntityReference>(entity, properties, siblingField, null, entity.GetAttributeValue <EntityReference>(siblingField) != null); }
private static void AddOptionSetValueNames <T>(LocalCrmDatabaseInfo info, T entity, EntityProperties properties) where T : Entity { foreach (var osvAttribute in entity.Attributes.Where(a => a.Value is OptionSetValue || (a.Value as AliasedValue)?.Value is OptionSetValue)) { PropertyInfo property; if (osvAttribute.Key == Email.Fields.StateCode) { property = properties.GetProperty(osvAttribute.Key); } else if (!properties.PropertiesByLowerCaseName.TryGetValue(osvAttribute.Key + "enum", out var lowerCaseProperties)) { if (!(osvAttribute.Value is AliasedValue aliased)) { continue; } // Handle Aliased Value var aliasedDictionary = PropertiesCache.For(info, aliased.EntityLogicalName).PropertiesByLowerCaseName; if (!aliasedDictionary.TryGetValue(aliased.AttributeLogicalName + "enum", out lowerCaseProperties)) { continue; } property = lowerCaseProperties.First(p => p.PropertyType.GenericTypeArguments.Length >= 1); entity.FormattedValues.Add(osvAttribute.Key, Enum.ToObject(property.PropertyType.GenericTypeArguments[0], ((OptionSetValue)aliased.Value).Value).ToString()); continue; } else { property = lowerCaseProperties.First(p => p.PropertyType.GenericTypeArguments.Length >= 1); } entity.FormattedValues.Add(osvAttribute.Key, property.GetValue(entity).ToString()); } }
/// <summary> /// Adds the value to the entity only if the attribute is valid for the entity, and the entity doesn't contain the value, or the value is null /// </summary> private static void AddValueIfNotPresent <T>(Entity entity, EntityProperties properties, string attributeName, T value) { ConditionallyAddValue(entity, properties, attributeName, value, entity.GetAttributeValue <object>(attributeName) == null); }
private static void UpdateOwningFieldsBasedOnOwner(LocalCrmDatabaseOrganizationService service, Entity entity, EntityProperties properties) { var ownerRef = entity.GetAttributeValue <EntityReference>(Email.Fields.OwnerId).Clone(); var owner = service.Retrieve(ownerRef.LogicalName, ownerRef.Id, new ColumnSet(true)); var bu = owner.GetAttributeValue <EntityReference>(SystemUser.Fields.BusinessUnitId) ?? owner.GetAttributeValue <EntityReference>(Email.Fields.OwningBusinessUnit); ownerRef.Name = null; // Clear Name value since owning field names aren't populated. var owningUser = owner.LogicalName == SystemUser.EntityLogicalName ? ownerRef : null; var owningTeam = owner.LogicalName == Team.EntityLogicalName ? ownerRef : null; ConditionallyAddValue(entity, properties, Email.Fields.OwningUser, owningUser); ConditionallyAddValue(entity, properties, Email.Fields.OwningTeam, owningTeam); if (bu == null) { return; } bu = bu.Clone(); bu.Name = null; ConditionallyAddValue(entity, properties, Email.Fields.OwningBusinessUnit, bu); ConditionallyAddValue(entity, properties, SystemUser.Fields.BusinessUnitId, bu); }
/// <summary> /// Sets the owner to the Info.User if it is null. Only to be called on Create. /// </summary> private static void SetOwnerForCreate(LocalCrmDatabaseOrganizationService service, Entity entity, EntityProperties properties) { if (entity.LogicalName == SystemUser.EntityLogicalName || entity.LogicalName == Team.EntityLogicalName) { AddValueIfNotPresent(entity, properties, SystemUser.Fields.BusinessUnitId, service.Info.BusinessUnit); return; } if (!properties.PropertiesByLogicalName.ContainsKey(Email.Fields.OwnerId)) { return; } AddValueIfNotPresent(entity, properties, Email.Fields.OwnerId, service.Info.User); UpdateOwningFieldsBasedOnOwner(service, entity, properties); }
private static void PopulateModifiedAttributes <T>(LocalCrmDatabaseInfo info, T entity, EntityProperties properties) where T : Entity { ConditionallyAddValue(entity, properties, Email.Fields.ModifiedBy, info.User, info.User.GetIdOrDefault() != Guid.Empty); ConditionallyAddValue(entity, properties, Email.Fields.ModifiedOnBehalfBy, info.UserOnBehalfOf, info.UserOnBehalfOf.GetIdOrDefault() != Guid.Empty); ConditionallyAddValue(entity, properties, Email.Fields.ModifiedOn, DateTime.UtcNow); }