Пример #1
0
        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;
 }