static IEnumerable <(PropertyInfo MainInfo, PropertyInfo DatabaseProp)> FilterProperties(PropertyInfo[] infos)
        {
            var nonCalculated = infos.Except(t => CalculatedAttribute.IsCalculated(t));
            var associations  = nonCalculated.Where(predicate => predicate.PropertyType.IsA <IEntity>());
            var rest          = nonCalculated.Except(associations);

            var ids = new List <PropertyInfo>();

            PropertyInfo getIdFor(PropertyInfo info)
            {
                var result = rest.FirstOrDefault(p => p.Name == info.Name.WithSuffix("Id"));

                ids.Add(result);
                return(result);
            }

            foreach (var prop in associations)
            {
                yield return(prop, getIdFor(prop));
            }

            foreach (var prop in rest.Except(ids))
            {
                yield return(prop, null);
            }
        }
        static IEnumerable <(PropertyInfo MainInfo, PropertyInfo DatabaseProp)> FilterProperties(PropertyInfo[] infos)
        {
            var nonCalculated = infos.Except(p => CalculatedAttribute.IsCalculated(p) || p.GetSetMethod() == null);
            var nonOverriden  = nonCalculated.Except(p => p.GetGetMethod() != p.GetGetMethod().GetBaseDefinition());
            var nonTransient  = nonOverriden.Except(p => TransientEntityAttribute.IsTransient(p.PropertyType));

            var associations = nonTransient.Where(p => p.IsAssociation());
            var rest         = nonTransient.Except(associations);

            var ids = new List <PropertyInfo>();

            PropertyInfo getIdFor(PropertyInfo info)
            {
                var result = rest.FirstOrDefault(p => p.Name == info.Name.WithSuffix("Id"));

                ids.Add(result);
                return(result);
            }

            foreach (var prop in associations)
            {
                yield return(prop, getIdFor(prop));
            }

            foreach (var prop in rest.Except(ids))
            {
                yield return(prop, null);
            }
        }
        static string GetPropertyExpression(MemberExpression memberInfo)
        {
            // Handle the member:
            var property = memberInfo.Member as PropertyInfo;

            if (property == null)
            {
                return(null);
            }

            // Fix for overriden properties:
            try { property = memberInfo.Expression.Type.GetProperty(property.Name) ?? property; }
            catch { }

            if (CalculatedAttribute.IsCalculated(property))
            {
                return(null);
            }
            if (memberInfo.Expression.Type.IsNullable())
            {
                return(property.Name);
            }
            if (!property.DeclaringType.Implements <IEntity>())
            {
                return(null);
            }

            // Handle the "member owner" expression:
            if (IsSimpleParameter(memberInfo.Expression))
            {
                if (property.Name.EndsWith("Id"))
                {
                    if (property.PropertyType == typeof(Guid) || property.PropertyType == typeof(Guid?))
                    {
                        return(property.Name.TrimEnd(2));
                    }
                }

                return(property.Name);
            }
            else if (memberInfo.Expression is MemberExpression)
            {
                // The expression is itself a member of something.

                var parentProperty = GetPropertyExpression(memberInfo.Expression as MemberExpression);
                if (parentProperty == null)
                {
                    return(null);
                }
                else
                {
                    return
                        (parentProperty + "." + property.Name);
                }
            }
            else
            {
                return(null);
            }
        }
Exemple #4
0
        /// <summary>
        /// Gets the data of a specified object's properties in a dictionary.
        /// </summary>
        public static Dictionary <string, string> GetDataToLog(IEntity entity)
        {
            var result = new Dictionary <string, string>();

            var type          = entity.GetType();
            var propertyNames = type.GetProperties().Select(p => p.Name).Distinct().Trim().ToArray();

            Func <string, PropertyInfo> getProperty = name => type.GetProperties()
                                                      .Except(p => p.IsSpecialName)
                                                      .Except(p => p.GetGetMethod().IsStatic)
                                                      .Except(p => p.Name == "ID")
                                                      .Where(p => p.GetSetMethod() != null && p.GetGetMethod().IsPublic)
                                                      .OrderByDescending(x => x.DeclaringType == type)
                                                      .FirstOrDefault(p => p.Name == name);

            var dataProperties = propertyNames.Select(getProperty).ExceptNull()
                                 .Except(x => CalculatedAttribute.IsCalculated(x))
                                 .Where(x => LogEventsAttribute.ShouldLog(x))
                                 .ToArray();

            foreach (var p in dataProperties)
            {
                var propertyType = p.PropertyType;

                string propertyValue;

                try
                {
                    if (propertyType == typeof(IList <Guid>))
                    {
                        propertyValue = (p.GetValue(entity) as IList <Guid>).ToString(",");
                    }
                    else if (propertyType.IsGenericType)
                    {
                        propertyValue = (p.GetValue(entity) as IEnumerable <object>).ToString(", ");
                    }
                    else
                    {
                        propertyValue = p.GetValue(entity).ToStringOrEmpty();
                    }

                    if (propertyValue.IsEmpty())
                    {
                        continue;
                    }
                }
                catch
                {
                    // No log needed
                    continue;
                }

                result.Add(p.Name, propertyValue);
            }

            return(result);
        }
        public void ConstructorTest()
        {
            // Arrange
            const bool IsCalculated = true;

            // Act
            var attr = new CalculatedAttribute(IsCalculated);

            // Assert
            Assert.AreEqual(IsCalculated, attr.IsCalculated);
        }
        public static PropertyInfo[] GetPropertiesInPath(this MemberExpression memberInfo)
        {
            var empty = new PropertyInfo[0];

            // Handle the member:
            var property = memberInfo.Member as PropertyInfo;

            if (property == null)
            {
                return(empty);
            }

            // Fix for overriden properties:
            try { property = memberInfo.Expression.Type.GetProperty(property.Name) ?? property; }
            catch { }

            if (CalculatedAttribute.IsCalculated(property))
            {
                return(empty);
            }

            if (memberInfo.Expression.IsSimpleParameter())
            {
                return new[] { property }
            }
            ;

            if (memberInfo.Expression is MemberExpression exp)
            {
                // The expression is itself a member of something.
                var parentProperty = exp.GetPropertiesInPath();

                if (parentProperty.None())
                {
                    return(empty);
                }

                return(parentProperty.Concat(property).ToArray());
            }

            if (memberInfo.Expression.Type.IsNullable())
            {
                return new[] { property }
            }
            ;

            return(empty);
        }
Exemple #7
0
        public IDictionary <string, Tuple <string, string> > GetUpdatedValues(IEntity original, IEntity updated)
        {
            if (original == null)
            {
                throw new ArgumentNullException(nameof(original));
            }

            var result = new Dictionary <string, Tuple <string, string> >();

            var type          = original.GetType();
            var propertyNames = type.GetProperties().Distinct().Select(p => p.Name.Trim()).ToArray();

            PropertyInfo getProperty(string name)
            {
                return(type.GetProperties()
                       .Except(p => p.IsSpecialName || p.GetGetMethod().IsStatic)
                       .Where(p => p.GetSetMethod() != null && p.GetGetMethod().IsPublic)
                       .OrderByDescending(x => x.DeclaringType == type)
                       .FirstOrDefault(p => p.Name == name));
            }

            var dataProperties = propertyNames.Select(getProperty).ExceptNull()
                                 .Except(x => CalculatedAttribute.IsCalculated(x))
                                 .Where(x => LogEventsAttribute.ShouldLog(x))
                                 .ToArray();

            foreach (var p in dataProperties)
            {
                var propertyType = p.PropertyType;
                // Get the original value:
                string originalValue, updatedValue = null;
                if (propertyType == typeof(IList <Guid>))
                {
                    try
                    {
                        originalValue = (p.GetValue(original) as IList <Guid>).ToString(",");
                        if (updated != null)
                        {
                            updatedValue = (p.GetValue(updated) as IList <Guid>).ToString(",");
                        }
                    }
                    catch
                    {
                        // No logging is needed.
                        continue;
                    }
                }
                else if (propertyType.IsGenericType)
                {
                    try
                    {
                        originalValue = (p.GetValue(original) as IEnumerable <object>).ToString(", ");
                        if (updated != null)
                        {
                            updatedValue = (p.GetValue(updated) as IEnumerable <object>).ToString(", ");
                        }
                    }
                    catch
                    {
                        // No logging is needed.
                        continue;
                    }
                }
                else
                {
                    try
                    {
                        originalValue = $"{p.GetValue(original)}";
                        if (updated != null)
                        {
                            updatedValue = $"{p.GetValue(updated)}";
                        }
                    }
                    catch
                    {
                        // No logging is needed
                        continue;
                    }
                }

                if (updated == null || originalValue != updatedValue)
                {
                    if (result.LacksKey(p.Name))
                    {
                        result.Add(p.Name, new Tuple <string, string>(originalValue, updatedValue));
                    }
                }
            }

            return(result);
        }