Example #1
0
    /// <summary>
    /// Constructs the decomposed objects as necessary.
    /// </summary>
    /// <param name="code">The code.</param>
    /// <param name="path">The path.</param>
    /// <param name="properties">The properties.</param>
    private static void ConstructDecomposedObjects(StringBuilder code, string path, PropertyMetadataCollection properties)
    {
        foreach (var property in properties)
        {
            if (property.Decompose)
            {
                if (property.CanWrite)
                {
                    code.AppendLine($"    if ({path}.{property.Name} == null)");
                    code.AppendLine($"    {path}.{property.Name} = new {property.PropertyType.FullName}();");
                }

                ConstructDecomposedObjects(code, path + "." + property.Name, MetadataCache.GetMetadata(property.PropertyType).Properties);
            }
        }
    }
Example #2
0
        internal ClassMetadata(TypeInfo typeInfo)
        {
            #if !DataAnnotations_Missing
            var table = (TableAttribute)typeInfo.GetCustomAttributes(typeof(TableAttribute), true).SingleOrDefault();
            if (table != null)
            {
                MappedTableName = table.Name;
                MappedSchemaName = table.Schema;
            }
            #endif

            #if Weird_Reflection
            var shadowingProperties = (from p in typeInfo.DeclaredProperties where IsHidingMember(p) select p).ToList();
            var propertyList = typeInfo.DeclaredProperties.ToList();
            #elif TypeInfo_Is_Not_Type
            var type = typeInfo.AsType();
            var shadowingProperties = (from p in type.GetProperties() where IsHidingMember(p) select p).ToList();
            var propertyList = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            #else
            var shadowingProperties = (from p in typeInfo.GetProperties() where IsHidingMember(p) select p).ToList();
            var propertyList = typeInfo.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            #endif

            Func<PropertyInfo, bool> IsHidden = propertyInfo => !shadowingProperties.Contains(propertyInfo) && shadowingProperties.Any(p => p.Name == propertyInfo.Name);

            Properties = new PropertyMetadataCollection(propertyList.Where(p => !IsHidden(p)).Select(p => new PropertyMetadata(p)));

            //List the properties that are affected when the indicated property is modified.
            foreach (var property in Properties)
                foreach (CalculatedFieldAttribute fieldList in property.PropertyInfo.GetCustomAttributes(typeof(CalculatedFieldAttribute), true))
                    foreach (var field in fieldList.SourceProperties)
                    {
                        if (!Properties.Contains(field))
                            throw new InvalidOperationException(string.Format("Cannot find property {0} on type {1}. This is needed for the calculated property {2}", field, typeInfo.FullName, property.Name));

                        Properties[field].AddCalculatedField(property);
                    }

            foreach (var property in Properties)
                property.EndInit();

            Constructors = new ConstructorMetadataCollection(typeInfo.DeclaredConstructors);
        }
Example #3
0
        /// <summary>
        /// Sets the properties.
        /// </summary>
        /// <param name="code">The code being generated.</param>
        /// <param name="columns">The columns in the data reader.</param>
        /// <param name="properties">The properties for the current object.</param>
        /// <param name="columnIndex">Index of the column being read.</param>
        /// <param name="path">The path to the object whose properties are being set.</param>
        /// <param name="decompositionPrefix">The decomposition prefix used when reading the column data.</param>
        private static void SetProperties(StringBuilder code, Dictionary <string, ColumnData> columns, PropertyMetadataCollection properties, int columnIndex, string path, string decompositionPrefix)
        {
            foreach (var property in properties)
            {
                if (property.Decompose)
                {
                    SetProperties(code, columns, MetadataCache.GetMetadata(property.PropertyType).Properties, columnIndex, path + "." + property.Name, decompositionPrefix + property.DecompositionPrefix);
                }

                if (property.MappedColumnName == null)
                {
                    continue;
                }

                ColumnData column;
                if (!columns.TryGetValue(decompositionPrefix + property.MappedColumnName, out column))
                {
                    continue; //not a valid column
                }
                if (column.Index != columnIndex)
                {
                    continue; //we'll get it on another iteration
                }
                if (property.PropertyType == column.ColumnType || (property.PropertyType.Name == "Nullable`1" && property.PropertyType.IsGenericType && property.PropertyType.GenericTypeArguments[0] == column.ColumnType))
                {
                    if (property.PropertyType.IsClass || (property.PropertyType.Name == "Nullable`1" && property.PropertyType.IsGenericType))
                    {
                        //null handler
                        code.AppendLine($"    if (reader.IsDBNull({column.Index}))");
                        code.AppendLine($"        {path}.{property.Name} = null;");
                        code.AppendLine($"    else");
                        code.AppendLine($"        {path}.{property.Name} = {column.Getter}({column.Index});");
                    }
                    else
                    {
                        //non-null handler
                        code.AppendLine($"    {path}.{property.Name} = {column.Getter}({column.Index});");
                    }
                }
                else //type casting is required
                {
                    var propertyTypeName = MetadataCache.GetMetadata(property.PropertyType).CSharpFullName;

                    if (property.PropertyType.IsClass || (property.PropertyType.Name == "Nullable`1" && property.PropertyType.IsGenericType))
                    {
                        //null handler
                        code.AppendLine($"    if (reader.IsDBNull({column.Index}))");
                        code.AppendLine($"        {path}.{property.Name} = null;");
                        code.AppendLine($"    else");
                        code.AppendLine($"        {path}.{property.Name} = ({propertyTypeName}){column.Getter}({column.Index});");
                    }
                    else
                    {
                        //non-null handler
                        code.AppendLine($"    {path}.{property.Name} = ({propertyTypeName}){column.Getter}({column.Index});");
                    }
                }
            }
        }
Example #4
0
    /// <summary>
    /// Sets the properties.
    /// </summary>
    /// <param name="code">The code being generated.</param>
    /// <param name="columns">The columns in the data reader.</param>
    /// <param name="properties">The properties for the current object.</param>
    /// <param name="columnIndex">Index of the column being read.</param>
    /// <param name="path">The path to the object whose properties are being set.</param>
    /// <param name="decompositionPrefix">The decomposition prefix used when reading the column data.</param>
    private static void SetProperties(StringBuilder code, Dictionary <string, ColumnData> columns, PropertyMetadataCollection properties, int columnIndex, string path, string?decompositionPrefix)
    {
        foreach (var property in properties)
        {
            if (property.Decompose)
            {
                SetProperties(code, columns, MetadataCache.GetMetadata(property.PropertyType).Properties, columnIndex, path + "." + property.Name, decompositionPrefix + property.DecompositionPrefix);
            }

            if (property.MappedColumnName == null)
            {
                continue;
            }

            if (!columns.TryGetValue(decompositionPrefix + property.MappedColumnName, out var column))
            {
                continue;                 //not a valid column
            }
            if (column.Index != columnIndex)
            {
                continue;                 //we'll get it on another iteration
            }
            if (property.PropertyType == column.ColumnType || (string.Equals(property.PropertyType.Name, "Nullable`1", StringComparison.Ordinal) && property.PropertyType.IsGenericType && property.PropertyType.GenericTypeArguments[0] == column.ColumnType))
            {
                if (column.IsNullable && (property.PropertyType.IsClass || (string.Equals(property.PropertyType.Name, "Nullable`1", StringComparison.Ordinal) && property.PropertyType.IsGenericType)))
                {
                    //null handler
                    code.AppendLine($"    if (reader.IsDBNull({column.Index}))");
                    code.AppendLine($"        {path}.{property.Name} = null;");
                    code.AppendLine($"    else");
                    code.AppendLine($"        {path}.{property.Name} = {column.Getter}({column.Index});");
                }
                else
                {
                    //non-null handler
                    code.AppendLine($"    {path}.{property.Name} = {column.Getter}({column.Index});");
                }
            }
            else             //type casting is required
            {
                var propertyTypeName = MetadataCache.GetMetadata(property.PropertyType).CSharpFullName;

                string getterWithConversion;
                string?tempVariable = null;

                //special handling for OleDB
                if ((property.PropertyType == typeof(TimeSpan) || property.PropertyType == typeof(TimeSpan?)) && column.ColumnType == typeof(string))
                {
                    getterWithConversion = $"TimeSpan.Parse({column.Getter}({column.Index}), System.Globalization.CultureInfo.InvariantCulture);";
                }
                else if ((property.PropertyType == typeof(TimeSpan) || property.PropertyType == typeof(TimeSpan?)) && column.ColumnType == typeof(object))
                {
                    getterWithConversion = $"TimeSpan.Parse((string){column.Getter}({column.Index}), System.Globalization.CultureInfo.InvariantCulture);";
                }
                else if ((property.PropertyType == typeof(TimeSpan) || property.PropertyType == typeof(TimeSpan?)) && column.ColumnType == typeof(DateTime))
                {
                    getterWithConversion = $"({column.Getter}({column.Index})).TimeOfDay";
                }
                else if ((property.PropertyType == typeof(TimeSpan) || property.PropertyType == typeof(TimeSpan?)) && column.ColumnType == typeof(DateTime))
                {
                    getterWithConversion = $"({column.Getter}({column.Index})).TimeOfDay";
                }
                else if (property.PropertyType == typeof(char) && column.ColumnType == typeof(string))
                {
                    tempVariable         = $"var temp{column.Index} = {column.Getter}({column.Index});";
                    getterWithConversion = $"temp{column.Index}.Length >= 1 ? temp{column.Index}[0] : default(char)";
                }
                else if (property.PropertyType == typeof(char?) && column.ColumnType == typeof(string))
                {
                    tempVariable         = $"var temp{column.Index} = {column.Getter}({column.Index});";
                    getterWithConversion = $"temp{column.Index}.Length >= 1 ? temp{column.Index}[0] : null";
                }

#if NET6_0_OR_GREATER
                else if ((property.PropertyType == typeof(DateOnly) || property.PropertyType == typeof(DateOnly?)) && column.ColumnType == typeof(DateTime))
                {
                    getterWithConversion = $"DateOnly.FromDateTime({column.Getter}({column.Index}))";
                }
                else if ((property.PropertyType == typeof(TimeOnly) || property.PropertyType == typeof(TimeOnly?)) && column.ColumnType == typeof(DateTime))
                {
                    getterWithConversion = $"TimeOnly.FromDateTime({column.Getter}({column.Index}))";
                }
                else if ((property.PropertyType == typeof(TimeOnly) || property.PropertyType == typeof(TimeOnly?)) && column.ColumnType == typeof(TimeSpan))
                {
                    getterWithConversion = $"TimeOnly.FromTimeSpan({column.Getter}({column.Index}))";
                }

                //special handling for OleDB
                else if ((property.PropertyType == typeof(TimeOnly) || property.PropertyType == typeof(TimeOnly?)) && column.ColumnType == typeof(string))
                {
                    getterWithConversion = $"TimeOnly.Parse({column.Getter}({column.Index}), System.Globalization.CultureInfo.InvariantCulture);";
                }
                else if ((property.PropertyType == typeof(TimeOnly) || property.PropertyType == typeof(TimeOnly?)) && column.ColumnType == typeof(object))
                {
                    getterWithConversion = $"TimeOnly.Parse((string){column.Getter}({column.Index}), System.Globalization.CultureInfo.InvariantCulture);";
                }
#endif
                else
                {
                    //simple casting
                    getterWithConversion = $"({propertyTypeName}){column.Getter}({column.Index})";
                }

                if (column.IsNullable && (property.PropertyType.IsClass || (string.Equals(property.PropertyType.Name, "Nullable`1", StringComparison.Ordinal) && property.PropertyType.IsGenericType)))
                {
                    //null handler
                    code.AppendLine($"    if (reader.IsDBNull({column.Index}))");
                    code.AppendLine($"        {path}.{property.Name} = null;");
                    code.AppendLine($"    else");
                    code.AppendLine("    {");
                    if (tempVariable != null)
                    {
                        code.AppendLine(tempVariable);
                    }
                    code.AppendLine($"        {path}.{property.Name} = {getterWithConversion};");
                    code.AppendLine("    }");
                }
                else
                {
                    //non-null handler
                    if (tempVariable != null)
                    {
                        code.AppendLine(tempVariable);
                    }
                    code.AppendLine($"    {path}.{property.Name} =  {getterWithConversion};");
                }
            }
        }
    }