public AttributeMetadata(EntityDefinition entityDefinition, PropertyInfo property) { EntityDefinition = entityDefinition; CrmMapping = property.GetCustomAttribute <CrmMappingAttribute>(); PropertyName = property.Name; if (CrmMapping == null) { return; } AttributeName = CrmMapping.AttributeName; IsKey = EntityDefinition.IsKey(AttributeName); IsPreferedKey = property.GetCustomAttribute <AlternateKeyAttribute>() != null; AttributeType = EntityDefinition.GetAttributeType(AttributeName); var typeConverterAttribute = property.GetCustomAttribute <TypeConverterAttribute>(); if (typeConverterAttribute != null) { var type1 = Type.GetType(typeConverterAttribute.ConverterTypeName.Substring(0, typeConverterAttribute.ConverterTypeName.IndexOf(','))); if (type1 != null) { TypeConverter = type1; } } ObjectType = property.PropertyType; if (property.PropertyType.GenericTypeArguments.Any()) { var subType = property.PropertyType.GenericTypeArguments.First(); if (typeof(Nullable <>).MakeGenericType(subType).IsAssignableFrom(ObjectType)) { ObjectType = subType; } } //Relationships = EntityDefinition.GetRelationshipsFromAttributeName(AttributeName).ToList(); LookupAttribute = property.GetCustomAttribute <CrmLookupAttribute>(); if (typeof(IBindingModel).IsAssignableFrom(property.PropertyType)) { SubEntity = EntityMetadata.GetMetadata(property.PropertyType); } SetMethod = property.SetMethod; Property = property; if (AttributeType == AttributeTypeCode.DateTime) { DateTimeBehavior = EntityDefinition.GetDateTimeBehavior(AttributeName); } }
public static IEnumerable <IBindingModel> GetDiff(this IEnumerable <IBindingModel> sourceList, IEnumerable <IBindingModel> targetEnumerable, Type modelType, IEqualityComparer <IBindingModel> comparer = null) { var metadata = EntityMetadata.GetMetadata(modelType); comparer = comparer ?? new KeyEqualityComparer(modelType); var targetList = targetEnumerable as IList <IBindingModel> ?? targetEnumerable.ToList(); var objectsToUpsert = sourceList.Except(targetList, new DeepModelEqualityComparer(modelType)); foreach (var obj in objectsToUpsert) { var existingObject = targetList.SingleOrDefault(o => comparer.Equals(obj, o)); if (!metadata.IsValidForCreate && existingObject == null) { continue; } yield return(existingObject == null ? obj : GetDiff(obj, existingObject)); } }
public static IBindingModel GetDiff(this IBindingModel source, IBindingModel target) { if (target == null) { return(source); } var metadata = EntityMetadata.GetMetadata(source.GetType()); var result = (IBindingModel)Activator.CreateInstance(source.GetType()); if (target.Id != Guid.Empty) { result.Id = target.Id; } else if (source.Id != Guid.Empty) { result.Id = source.Id; } foreach (var attribute in metadata.CrmAttributes.Where(a => a.CrmMapping.IsValidForUpdate)) { if (source is BindingModelBase) { if (!((BindingModelBase)source).InitializedProperties.Contains(attribute.PropertyName)) { continue; } } var valueSource = attribute.Property.GetValue(source); var valueTarget = attribute.Property.GetValue(target); switch (attribute.AttributeType) { case AttributeTypeCode.DateTime: if (attribute.DateTimeBehavior == DateTimeBehavior.UserLocal) { valueSource = ((DateTime?)valueSource)?.ToUniversalTime(); valueTarget = ((DateTime?)valueTarget)?.ToUniversalTime(); } else { valueSource = valueSource != null ? (DateTime?)new DateTime(((DateTime)valueSource).Ticks, DateTimeKind.Utc) : null; } break; case AttributeTypeCode.String: case AttributeTypeCode.Memo: if (string.Empty == (valueSource as string)) { valueSource = null; } break; } if ((!attribute.IsKey || result.Id != Guid.Empty) && ( (valueSource == null && valueTarget == null) || (valueSource != null && valueSource.Equals(valueTarget)) || (valueTarget != null && valueTarget.Equals(valueSource)) ) ) { continue; } attribute.Property.SetValue(result, valueSource); } return(result); }
public DeepModelEqualityComparer(Type modelType) { Metadata = EntityMetadata.GetMetadata(modelType); }
public KeyEqualityComparer(Type modelType) { Metadata = EntityMetadata.GetMetadata(modelType); HasPreferedKey = Metadata.HasPreferedKey; }