Esempio n. 1
0
        /// <summary>
        /// Coerces an IDataReader to try and load an object using name/property matching
        /// </summary>
        public static void Load <T>(this IDataReader rdr, T item, List <string> ColumnNames) //mike added ColumnNames
        {
            Type iType = typeof(T);

            PropertyInfo[] cachedProps  = iType.GetProperties();
            FieldInfo[]    cachedFields = iType.GetFields();

            PropertyInfo currentProp;
            FieldInfo    currentField = null;

            for (int i = 0; i < rdr.FieldCount; i++)
            {
                string pName = rdr.GetName(i);
                currentProp = cachedProps.SingleOrDefault(x => x.Name.Equals(pName, StringComparison.InvariantCultureIgnoreCase));

                //mike if the property is null and ColumnNames has data then look in ColumnNames for match
                if (currentProp == null && ColumnNames != null && ColumnNames.Count > i)
                {
                    currentProp = cachedProps.First(x => x.Name == ColumnNames[i]);
                }

                //if the property is null, likely it's a Field
                if (currentProp == null)
                {
                    currentField = cachedFields.SingleOrDefault(x => x.Name.Equals(pName, StringComparison.InvariantCultureIgnoreCase));
                }

                if (currentProp != null && !DBNull.Value.Equals(rdr.GetValue(i)))
                {
                    Type valueType = rdr.GetValue(i).GetType();
                    if (valueType == typeof(Boolean))
                    {
                        string value = rdr.GetValue(i).ToString();
                        currentProp.SetValue(item, value == "1" || value == "True", null);
                    }
                    else if (currentProp.PropertyType == typeof(Guid))
                    {
                        currentProp.SetValue(item, rdr.GetGuid(i), null);
                    }
                    else if (Objects.IsNullableEnum(currentProp.PropertyType))
                    {
                        var nullEnumObjectValue = Enum.ToObject(Nullable.GetUnderlyingType(currentProp.PropertyType), rdr.GetValue(i));
                        currentProp.SetValue(item, nullEnumObjectValue, null);
                    }
                    else if (currentProp.PropertyType.IsEnum)
                    {
                        var    flags = currentProp.PropertyType.GetCustomAttributes(typeof(FlagsAttribute), false);
                        Object enumValue;
                        if (flags.Length > 0)
                        {
                            // Find the static TryParse() method.
                            var tryParseInfo =
                                currentProp.PropertyType.BaseType.GetMethods(BindingFlags.Static | BindingFlags.Public)[1];// currentProp.PropertyType.GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public);
                            if (tryParseInfo == null)
                            {
                                break;
                            }

                            var parseMethod  = tryParseInfo.MakeGenericMethod(currentProp.PropertyType);
                            var methodParams = new[] { rdr.GetValue(i), false, Activator.CreateInstance(currentProp.PropertyType, true) };
                            parseMethod.Invoke(null, methodParams);

                            enumValue = methodParams[2]; //Enum.TryParse<Enum>(rdr.GetValue(i), false, out enumValue);
                        }
                        else
                        {
                            enumValue = Enum.ToObject(currentProp.PropertyType, rdr.GetValue(i));
                        }

                        currentProp.SetValue(item, enumValue, null);
                    }
                    else
                    {
                        var val     = rdr.GetValue(i);
                        var valType = val.GetType();
                        var attribs =
                            currentProp.GetCustomAttributes(
                                typeof(SubSonic.SqlGeneration.Schema.SubSonicTypeConversionAttribute),
                                true
                                );
                        //try to assign it
                        if (attribs != null && attribs.Length == 1)
                        {   // ZJG: Use the conversion method provided via this type's metadata.
                            var converter = (SubSonic.SqlGeneration.Schema.SubSonicTypeConversionAttribute)attribs[0];
                            var newVal    = converter.Convert(
                                val,
                                SubSonic.SqlGeneration.Schema.TypeConversionDirection.DatabaseToProperty
                                );
                            currentProp.SetValue(item, newVal, null);
                        }
                        else if (currentProp.PropertyType.IsAssignableFrom(valueType))
                        {
                            currentProp.SetValue(item, val, null);
                        }
                        else
                        {
                            currentProp.SetValue(item, val.ChangeTypeTo(currentProp.PropertyType), null);
                        }
                    }
                }
                else if (currentField != null && !DBNull.Value.Equals(rdr.GetValue(i)))
                {
                    Type valueType = rdr.GetValue(i).GetType();
                    if (valueType == typeof(Boolean))
                    {
                        string value = rdr.GetValue(i).ToString();
                        currentField.SetValue(item, value == "1" || value == "True");
                    }
                    else if (currentField.FieldType == typeof(Guid))
                    {
                        currentField.SetValue(item, rdr.GetGuid(i));
                    }
                    else if (Objects.IsNullableEnum(currentField.FieldType))
                    {
                        var nullEnumObjectValue = Enum.ToObject(Nullable.GetUnderlyingType(currentField.FieldType), rdr.GetValue(i));
                        currentField.SetValue(item, nullEnumObjectValue);
                    }
                    else
                    {
                        var val     = rdr.GetValue(i);
                        var valType = val.GetType();
                        //try to assign it
                        if (currentField.FieldType.IsAssignableFrom(valueType))
                        {
                            currentField.SetValue(item, val);
                        }
                        else
                        {
                            currentField.SetValue(item, val.ChangeTypeTo(currentField.FieldType));
                        }
                    }
                }
            }

            if (item is IActiveRecord)
            {
                var arItem = (IActiveRecord)item;
                arItem.SetIsLoaded(true);
                arItem.SetIsNew(false);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Coerces an IDataReader to try and load an object using name/property matching
        /// </summary>
        public static void Load <T>(this IDataReader rdr, T item, List <string> ColumnNames) //mike added ColumnNames
        {
            Type iType = typeof(T);

            PropertyInfo[] cachedProps  = iType.GetProperties();
            FieldInfo[]    cachedFields = iType.GetFields();

            PropertyInfo currentProp;
            FieldInfo    currentField = null;

            for (int i = 0; i < rdr.FieldCount; i++)
            {
                string pName = rdr.GetName(i);
                currentProp = cachedProps.SingleOrDefault(x => x.Name.Equals(pName, StringComparison.InvariantCultureIgnoreCase));

                //mike if the property is null and ColumnNames has data then look in ColumnNames for match
                if (currentProp == null && ColumnNames != null && ColumnNames.Count > i)
                {
                    currentProp = cachedProps.First(x => x.Name == ColumnNames[i]);
                }

                //if the property is null, likely it's a Field
                if (currentProp == null)
                {
                    currentField = cachedFields.SingleOrDefault(x => x.Name.Equals(pName, StringComparison.InvariantCultureIgnoreCase));
                }

                if (currentProp != null && !DBNull.Value.Equals(rdr.GetValue(i)))
                {
                    Type valueType = rdr.GetValue(i).GetType();
                    if (valueType == typeof(Boolean))
                    {
                        string value = rdr.GetValue(i).ToString();
                        currentProp.SetValue(item, value == "1" || value == "True", null);
                    }
                    else if (currentProp.PropertyType == typeof(Guid))
                    {
                        currentProp.SetValue(item, rdr.GetGuid(i), null);
                    }
                    else if (Objects.IsNullableEnum(currentProp.PropertyType))
                    {
                        var nullEnumObjectValue = Enum.ToObject(Nullable.GetUnderlyingType(currentProp.PropertyType), rdr.GetValue(i));
                        currentProp.SetValue(item, nullEnumObjectValue, null);
                    }
                    else
                    {
                        var val     = rdr.GetValue(i);
                        var valType = val.GetType();
                        //try to assign it
                        if (val.GetType().IsAssignableFrom(valueType))
                        {
                            currentProp.SetValue(item, val, null);
                        }
                        else
                        {
                            currentProp.SetValue(item, rdr.GetValue(i).ChangeTypeTo(valueType), null);
                        }
                    }
                }
                else if (currentField != null && !DBNull.Value.Equals(rdr.GetValue(i)))
                {
                    Type valueType = rdr.GetValue(i).GetType();
                    if (valueType == typeof(Boolean))
                    {
                        string value = rdr.GetValue(i).ToString();
                        currentField.SetValue(item, value == "1" || value == "True");
                    }
                    else if (currentField.FieldType == typeof(Guid))
                    {
                        currentField.SetValue(item, rdr.GetGuid(i));
                    }
                    else if (Objects.IsNullableEnum(currentField.FieldType))
                    {
                        var nullEnumObjectValue = Enum.ToObject(Nullable.GetUnderlyingType(currentField.FieldType), rdr.GetValue(i));
                        currentField.SetValue(item, nullEnumObjectValue);
                    }
                    else
                    {
                        currentField.SetValue(item, rdr.GetValue(i).ChangeTypeTo(valueType));
                    }
                }
            }

            if (item is IActiveRecord)
            {
                var arItem = (IActiveRecord)item;
                arItem.SetIsLoaded(true);
                arItem.SetIsNew(false);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Coerces an IDataReader to try and load an object using name/property matching
        /// </summary>
        /// <remarks>
        /// WARNING: There is a bug in this method. If the passed in ColumnNames and the actual column
        /// order in the data reader aren't the same (which they may not be if you are doing some table
        /// joins and a projection into an object)
        /// then this method might put the wrong data into the wrong properties of the object.
        /// The passed in "ColumnNames" aren't actually the DB column names, they are the projection
        /// object's property names. This code is assuming that the object's properties are in the same
        /// order as the DB query's returned columns. (Jeff V.)
        /// </remarks>
        public static void Load <T>(this IDataReader rdr, T item, List <string> ColumnNames, PropertyInfo[] cachedProps, FieldInfo[] cachedFields) //mike added ColumnNames
        {
            Type iType = typeof(T);

            // Avoid enumerating properties looking for matching name (performs poorly on large result sets)
            Dictionary <string, PropertyInfo> cachedPropsByLowerName  = cachedProps.ToDictionary(x => x.Name.ToLower(), x => x);
            Dictionary <string, FieldInfo>    cachedFieldsByLowerName = cachedFields.ToDictionary(x => x.Name.ToLower(), x => x);
            List <string> columnNamesLower = ColumnNames == null
                                                ? new List <string>()
                                                : ColumnNames.Select(x => x.ToLower()).ToList();

            PropertyInfo currentProp;
            FieldInfo    currentField = null;

            for (int i = 0; i < rdr.FieldCount; i++)
            {
                /* These 2 lines can cause a bug, because it tries to find an object property named the same as
                 * a DB column name, which isnt always what the user wanted. Take for example:
                 *
                 * var o = from t in db.SomeTable
                 *         where t.COL1 == 'foo'
                 *         select new()
                 *         {
                 *           COL1 = t.COL2,
                 *           COL2 = t.COL1
                 *         }
                 *
                 * In this case, the object returned by this method will end up with the properties mapped in reverse
                 *  (o.COL1 = t.COL1, o.COL2 = t.COL2 instead of the requested o.COL1 = t.COL2, o.COL2 = t.COL1)
                 *
                 * (Jeff V.)
                 */
                string pName      = rdr.GetName(i);
                string pNameLower = pName.ToLower();

                //currentProp = cachedProps.SingleOrDefault(x => x.Name.Equals(pName, StringComparison.InvariantCultureIgnoreCase));
                cachedPropsByLowerName.TryGetValue(pNameLower, out currentProp);

                //mike if the property is null and ColumnNames has data then look in ColumnNames for match

                /* This can cause a bug because it assumes ColumnNames is in the same order as the columns
                 * returned by the database, which is not always true.
                 *
                 * It will assign 'rdr.GetValue(i)' to the object property named 'ColumnNames[i]'
                 * but there is no guarantee that rdr's columns and ColumnNames' columns are actually in
                 * the same order as defined by the projection. This leads to some values being assigned
                 * the the wrong property.
                 *
                 * (Jeff V.)
                 */
                if (currentProp == null && ColumnNames != null && ColumnNames.Count > i)
                {
                    //currentProp = cachedProps.First(x => x.Name == ColumnNames[i]);
                    cachedPropsByLowerName.TryGetValue(columnNamesLower[i], out currentProp);
                }

                //if the property is null, likely it's a Field
                if (currentProp == null)
                {
                    cachedFieldsByLowerName.TryGetValue(pNameLower, out currentField);
                }
                //currentField = cachedFields.SingleOrDefault(x => x.Name.Equals(pName, StringComparison.InvariantCultureIgnoreCase));

                var value = rdr.GetValue(i);
                if (currentProp != null && !DBNull.Value.Equals(value))
                {
                    Type valueType = value.GetType();
                    if (valueType == typeof(Boolean))
                    {
                        string valueStr = value.ToString();
                        currentProp.SetValue(item, valueStr == "1" || valueStr == "True", null);
                    }
                    else if (currentProp.PropertyType == typeof(Guid))
                    {
                        if (rdr[i] is Guid)
                        {
                            currentProp.SetValue(item, rdr.GetGuid(i), null);
                        }
                        else
                        {
                            string guidInString = rdr.GetString(i);
                            Guid   guid         = new Guid(guidInString);
                            currentProp.SetValue(item, guid, null);
                        }
                    }
                    else if (Objects.IsNullableEnum(currentProp.PropertyType))
                    {
                        var nullEnumObjectValue = Enum.ToObject(Nullable.GetUnderlyingType(currentProp.PropertyType), value);
                        currentProp.SetValue(item, nullEnumObjectValue, null);
                    }
                    else if (currentProp.PropertyType.IsEnum)
                    {
                        var enumValue = Enum.ToObject(currentProp.PropertyType, value);
                        currentProp.SetValue(item, enumValue, null);
                    }
                    else
                    {
                        //try to assign it
                        if (currentProp.PropertyType.IsAssignableFrom(valueType))
                        {
                            currentProp.SetValue(item, value, null);
                        }
                        else
                        {
                            currentProp.SetValue(item, value.ChangeTypeTo(currentProp.PropertyType), null);
                        }
                    }
                }
                else if (currentField != null && !DBNull.Value.Equals(value))
                {
                    Type valueType = value.GetType();
                    if (valueType == typeof(Boolean))
                    {
                        string valueStr = value.ToString();
                        currentField.SetValue(item, valueStr == "1" || valueStr == "True");
                    }
                    else if (currentField.FieldType == typeof(Guid))
                    {
                        currentField.SetValue(item, rdr.GetGuid(i));
                    }
                    else if (Objects.IsNullableEnum(currentField.FieldType))
                    {
                        var nullEnumObjectValue = Enum.ToObject(Nullable.GetUnderlyingType(currentField.FieldType), value);
                        currentField.SetValue(item, nullEnumObjectValue);
                    }
                    else
                    {
                        //try to assign it
                        if (currentField.FieldType.IsAssignableFrom(valueType))
                        {
                            currentField.SetValue(item, value);
                        }
                        else
                        {
                            currentField.SetValue(item, value.ChangeTypeTo(currentField.FieldType));
                        }
                    }
                }
            }

            if (item is IActiveRecord)
            {
                var arItem = (IActiveRecord)item;
                arItem.SetIsLoaded(true);
                arItem.SetIsNew(false);
            }
        }