Ejemplo n.º 1
0
        /// <summary>
        /// Convert an Oracle entity/object name (table, package, argument, column etc.) to a valid C# equivalent
        /// </summary>
        /// <param name="oracleArgName"></param>
        /// <param name="useCamelCase">convert to camelCase, otherwise defaults to PascalCase</param>
        /// <returns></returns>
        internal static string ConvertOracleNameToCSharpName(string oracleName, bool useCamelCase)
        {
            if (String.IsNullOrEmpty(oracleName))
            {
                return(null);                                  // this occurs with a return arg
            }
            String oracleNameAdjusted = oracleName;

            // replace special characters with alphabetic equivalent
            oracleNameAdjusted = oracleNameAdjusted.Replace(@"!", "exclamationpoint" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@"@", "at" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@"#", "pound" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@"$", "dollar" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@"%", "percent" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@"^", "caret" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@"&", "ampersand" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@"*", "asterisk" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@"-", "dash" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@"+", "plus" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@"=", "equals" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@".", "period" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@"?", "questionmark" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@":", "colon" + CHARACTER_ABBREV);
            oracleNameAdjusted = oracleNameAdjusted.Replace(@";", "semicolon" + CHARACTER_ABBREV);

            String cSharpName = (useCamelCase
                ? CaseConverter.ConvertUnderscoreDelimitedToCamelCase(oracleNameAdjusted)
                : CaseConverter.ConvertUnderscoreDelimitedToPascalCase(oracleNameAdjusted));

            if (Char.IsDigit(cSharpName, 0))
            {
                cSharpName = (useCamelCase ? "t" : "T") + "he" + cSharpName;                               // a C# arg cannot start with number
            }
            if (CSharp.IsKeyword(cSharpName))
            {
                cSharpName = cSharpName + "Cs";                               // append text to avoid the C# keyword
            }
            return(cSharpName);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Return a generic list of objects fetched from a data reader using type-specific read method
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="reader"></param>
        /// <param name="readMethod"></param>
        /// <returns></returns>
        //public static List<T> ReadResult<T>(OracleDataReader reader, Func<OracleDataReader, T> readMethod)  {

        //    // iterate reader and create list of BOs using they type's reader method
        //    List<T> list = new List<T>();
        //    if (reader.HasRows) while (reader.Read() == true) list.Add(readMethod(reader));
        //    return list;
        //}

        /// <summary>
        /// Return a Datatable fetched from a data reader
        /// </summary>
        /// <param name="reader">Reader prepared for fetching result set</param>
        /// <returns></returns>
        public static DataTable ReadResult(OracleDataReader reader, bool convertColumnNameToTitleCaseInCaption = false, UInt32?optionalMaximumNumberOfRowsToRead = null)
        {
            // determine name and type of each column in result set and build empty datatable
            DataTable     dt = new DataTable();
            DataColumn    dc;
            List <string> colName = new List <string>();

            // column names and respective Oracle type from the reader
            List <Column> readerColumns = GetReaderColumnTypes(reader);

            // build empty datatable with column names and correct C# type
            foreach (Column col in readerColumns)
            {
                // add column to list
                colName.Add(col.ColumnName);

                // create data column object based on Oracle column type, save column type to array
                if (col.ColumnType == typeof(OracleString))
                {
                    dc = new DataColumn(col.ColumnName, typeof(System.String));
                }
                else if (col.OracleDataTypeName.Equals(OracleDbType.BinaryDouble.ToString()))
                {
                    dc = new DataColumn(col.ColumnName, typeof(System.Double));
                }
                else if (col.OracleDataTypeName.Equals(OracleDbType.BinaryFloat.ToString()))
                {
                    dc = new DataColumn(col.ColumnName, typeof(System.Single));
                }
                else if (col.ColumnType == typeof(OracleDecimal))
                {
                    dc = new DataColumn(col.ColumnName, typeof(OracleDecimal));
                }
                else if (col.ColumnType == typeof(OracleDate))
                {
                    dc = new DataColumn(col.ColumnName, typeof(OracleDate));
                }
                else if (col.ColumnType == typeof(OracleTimeStamp))
                {
                    dc = new DataColumn(col.ColumnName, typeof(OracleTimeStamp));
                }
                else if (col.ColumnType == typeof(OracleTimeStampLTZ))
                {
                    dc = new DataColumn(col.ColumnName, typeof(OracleTimeStampLTZ));
                }
                else if (col.ColumnType == typeof(OracleTimeStampTZ))
                {
                    dc = new DataColumn(col.ColumnName, typeof(OracleTimeStampTZ));
                }
                else
                {
                    dc = new DataColumn(col.ColumnName, typeof(Object));
                }
                //throw new Exception("Oracle column type not recognized in 'DataTable Hydrator.ReadResult()' for database column " + col.ColumnName);

                dc.Caption =
                    convertColumnNameToTitleCaseInCaption ?
                    CaseConverter.ConvertSnakeCaseToLabel(col.ColumnName)
                    : col.ColumnName
                ;
                dt.Columns.Add(dc);
            }

            // add rows to data table
            DataRow drow;
            Int32   numRowsRead = 0;

            if (reader != null && reader.HasRows)
            {
                while (reader.Read())
                {
                    // create the row and set column data based on result set row
                    drow = dt.NewRow();
                    for (int c = 0; c < colName.Count; c++)
                    {
                        if (reader.IsDBNull(reader.GetOrdinal(colName[c])))
                        {
                            drow[colName[c]] = DBNull.Value;
                        }
                        else if (readerColumns[c].OracleDataTypeName.Equals(OracleDbType.BinaryDouble.ToString()))
                        {
                            drow[colName[c]] = (Double?)reader.GetDouble(reader.GetOrdinal(colName[c]));
                        }
                        else if (readerColumns[c].OracleDataTypeName.Equals(OracleDbType.BinaryFloat.ToString()))
                        {
                            drow[colName[c]] = (Single?)reader.GetFloat(reader.GetOrdinal(colName[c]));
                        }
                        else if (readerColumns[c].ColumnType == typeof(OracleString))
                        {
                            drow[colName[c]] = (String)reader.GetOracleString(reader.GetOrdinal(colName[c]));
                        }
                        else if (readerColumns[c].ColumnType == typeof(OracleDecimal))
                        {
                            drow[colName[c]] = (OracleDecimal?)OracleDecimal.SetPrecision(reader.GetOracleDecimal(reader.GetOrdinal(colName[c])), 28);
                        }
                        else if (readerColumns[c].ColumnType == typeof(OracleDate))
                        {
                            drow[colName[c]] = (OracleDate?)reader.GetOracleDate(reader.GetOrdinal(colName[c]));
                        }
                        else if (readerColumns[c].ColumnType == typeof(OracleTimeStamp))
                        {
                            drow[colName[c]] = (OracleTimeStamp?)reader.GetOracleTimeStamp(reader.GetOrdinal(colName[c]));
                        }
                        else if (readerColumns[c].ColumnType == typeof(OracleTimeStampLTZ))
                        {
                            drow[colName[c]] = (OracleTimeStampLTZ?)reader.GetOracleTimeStampLTZ(reader.GetOrdinal(colName[c]));
                        }
                        else if (readerColumns[c].ColumnType == typeof(OracleTimeStampTZ))
                        {
                            drow[colName[c]] = (OracleTimeStampTZ?)reader.GetOracleTimeStampTZ(reader.GetOrdinal(colName[c]));
                        }
                        else
                        {
                            drow[colName[c]] = reader.GetValue(reader.GetOrdinal(colName[c]));
                        }
                    }

                    // Add the hydrated row to the datatable
                    dt.Rows.Add(drow);

                    if (optionalMaximumNumberOfRowsToRead != null)
                    {
                        numRowsRead++;
                        if (numRowsRead >= optionalMaximumNumberOfRowsToRead)
                        {
                            break;
                        }
                    }
                }
            }

            // this is necessary in order for DataRowVersion status to be correct
            dt.AcceptChanges();

            return(dt);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Build list of column to property/field mappings for a given C# class type and a data reader
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="reader"></param>
        /// <param name="mapByPosition"></param>
        /// <param name="allowUnmappedColumns"></param>
        /// <returns></returns>
        private static List <ColumnMapping> BuildMappings <T>(OracleDataReader reader, bool mapByPosition, bool allowUnmappedColumns)
        {
            // extract all settable public properties of the type (includes inherited)
            PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

            // if mapping by name, extract all settable protected and private fields (includes inherited)
            FieldInfo[] fields = null;
            if (!mapByPosition)
            {
                fields = typeof(T).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
            }

            // when mapping by position, filter out properties that do not have a map position set in the attribute
            if (mapByPosition)
            {
                properties = properties.Select(x => new {
                    Property  = x,
                    Attribute = (HydratorMapAttribute)Attribute.GetCustomAttribute(x, typeof(HydratorMapAttribute))
                })
                             .Where(x => x.Attribute != null && x.Attribute.Position >= 0).OrderBy(x => x.Attribute.Position) // important to order by position
                             .Select(x => x.Property).ToArray();

                // Never allow the number of properties with the position attribute to be greater than the column count. This means the BO is looking for
                //  a column that is not there.
                if (properties.Length > reader.FieldCount)
                {
                    throw new Exception("Hydrator.BuildMappings<T>() - number of settable properties with a position attribute in " + typeof(T).FullName
                                        + "(" + properties.Length + ") is greater than the number of columns in the reader(" + reader.FieldCount + ").");

                    // If not allowed, the number of properties with the position attribute cannot be less than the column count, meaning no column should be ignored.
                }
                else if (!allowUnmappedColumns && properties.Length < reader.FieldCount)
                {
                    throw new Exception("Hydrator.BuildMappings<T>() - number of settable properties with a position attribute in " + typeof(T).FullName
                                        + "(" + properties.Length + ") is less than the number of columns the reader(" + reader.FieldCount + "), meaning a column has been unmapped.");
                }
            }

            List <ColumnMapping> mappings = new List <ColumnMapping>(); // holds all column mappings for a result set

            for (int c = 0; c < reader.FieldCount; c++)                 // loop reader columns
            {
                PropertyInfo property;

                // map by position works only with properties (not fields)
                if (mapByPosition)
                {
                    if (c > properties.Length - 1)
                    {
                        break; // there are more columns than map properties, so our mapping is complete
                    }
                    else
                    {
                        property = properties[c]; // get the next property to be mapped
                    }
                    // Always check property position against column position at this point since the properties are sorted. If they
                    //  don't match, something is definitely wrong in the attribute settings.
                    int propertyMapPosition = ((HydratorMapAttribute)Attribute.GetCustomAttribute(property, typeof(HydratorMapAttribute))).Position;
                    if (c != propertyMapPosition)
                    {
                        throw new Exception("Hydrator.BuildMappings<T>() - property map position mismatch with reader columns near property position " + propertyMapPosition.ToString()
                                            + " on class " + typeof(T).FullName + "." + " Check for duplicate or missing position values on properties.");
                    }

                    // valid property found, add completed mapping to our list
                    mappings.Add(new ColumnMapping(new Column(reader.GetName(c), reader.GetProviderSpecificFieldType(c), reader.GetDataTypeName(c)), property));

                    // mapping by name
                }
                else
                {
                    // look first for an _underscorePrefixedCamelCase field, and then a camelCase field (both are non-public)
                    FieldInfo field = Array.Find(fields, f => f.Name == CaseConverter.ConvertSnakeCaseToCamelCasePrefixedWithUnderscore(reader.GetName(c)))
                                      ?? Array.Find(fields, f => f.Name == CaseConverter.ConvertSnakeCaseToCamelCase(reader.GetName(c)));
                    if (field != default(FieldInfo))
                    {
                        // valid field found, add completed column mapping to our list
                        mappings.Add(new ColumnMapping(new Column(reader.GetName(c), reader.GetProviderSpecificFieldType(c), reader.GetDataTypeName(c)), field));
                    }
                    else     // otherwise, look for a PascalCase property (public) since field not found
                    {
                        property = Array.Find(properties, p => p.Name == CaseConverter.ConvertSnakeCaseToPascalCase(reader.GetName(c)));
                        if (property != default(PropertyInfo))   // this is equivalent to a "not null" compare
                        // valid property found, add completed mapping to our list
                        {
                            mappings.Add(new ColumnMapping(new Column(reader.GetName(c), reader.GetProviderSpecificFieldType(c), reader.GetDataTypeName(c)), property));
                        }
                        else
                        {
                            // a property does not exist, so the column has neither property nor field to map to
                            if (allowUnmappedColumns)
                            {
                                continue; // unmapped column will be ignored - a "silent failed mapping"
                            }
                            else
                            {
                                throw new Exception("Hydrator.BuildMappings() - Could not find an _underscorePrefixedCamelCase non-public field, "
                                                    + "a camelCase non-public field, nor a PascalCase public property on " + typeof(T).FullName + " for column " + reader.GetName(c));
                            }
                        }
                    } // if field not found
                }     // mapping by name
            }         // loop reader columns

            return(mappings);
        }