예제 #1
0
        /// <summary>
        ///  Creates an object of type <typeparamref name="T"/> based on a <see cref="DataRow"/>.
        ///  The fields of the <see cref="DataRow"/> can be either of the corresponding type, or of the
        ///  <see cref="String"/> type. In the case of a <see cref="String"/>, conversion will be done using
        ///  the <see cref="PIn"/> data class.
        /// </summary>
        /// <param name="row">
        ///  A <see cref="DataRow"/> containing rows corresponding to objects of type <typeparamref name="T"/>.
        /// </param>
        /// <returns>
        ///  An objects of type <typeparamref name="T"/>.
        /// </returns>
        /// <remarks>
        ///  <para>
        ///  This method is for compatibility purposes only.
        ///  </para>
        ///  <para>
        ///  This method needs to be tested.
        ///  </para>
        /// </remarks>
        public static T CreateObject(DataRow row)
        {
            if (row == null)
            {
                throw new ArgumentNullException("row");
            }

            Collection <T>             values     = new Collection <T>();
            Collection <DataFieldInfo> dataFields = DataObjectInfo <T> .GetDataFields();

            T value = new T();

            foreach (DataFieldInfo dataField in dataFields)
            {
                if (dataField.WriteOnly)
                {
                    continue;
                }

                // Retrieve the value and its type, both in the database and code.
                object dataValue = row[dataField.DatabaseName];
                Type   dataType  = row.Table.Columns[dataField.DatabaseName].DataType;
                Type   codeType  = dataField.Field.FieldType;

                if (codeType != typeof(string) && dataType == typeof(string))
                {
                    // If the type in the dataset is "string", but the type in the code
                    // object isn't "string", we use the PIn class.
                    if (dataType == typeof(Bitmap))
                    {
                        dataValue = PIn.PBitmap((string)dataValue);
                    }
                    else if (dataType == typeof(bool))
                    {
                        dataValue = PIn.PBool((string)dataValue);
                    }
                    else if (dataType == typeof(Byte))
                    {
                        dataValue = PIn.PByte((string)dataValue);
                    }
                    else if (dataType == typeof(DateTime))
                    {
                        // NOTE: Is there any difference between PIn.PDate and PIn.PDateT?
                        dataValue = PIn.PDate((string)dataValue);
                    }
                    else if (dataType == typeof(double))
                    {
                        dataValue = PIn.PDouble((string)dataValue);
                    }
                    else if (dataType == typeof(float))
                    {
                        dataValue = PIn.PFloat((string)dataValue);
                    }
                    else if (dataType == typeof(int))
                    {
                        dataValue = PIn.PInt((string)dataValue);
                    }
                    else
                    {
                        // NOTE: Support for "Sound" is not here yet. Maybe it should be exported
                        // to a byte[] type and then saved, don't know.
                        throw new NotSupportedException(Resources.DataTypeNotSupportedByPIn);
                    }
                }
                else
                {
                    // The object is stored in it's "true" type in the DataSet as well (no conversions to
                    // string types have been done). We can, normally, directly use it, except for a couple
                    // of special cases.

                    if (codeType == typeof(bool))
                    {
                        // Booleans are sometimes stored as TINYINT(3), to enable conversion to
                        // Enums if required. Hence, we need to do an explicit conversion.
                        dataField.Field.SetValue(value, Convert.ToBoolean(dataValue));
                    }
                    else if (codeType == typeof(DateTime))
                    {
                        // DateTime fields can have various minimum or default values depending on
                        // the database type. In MySql, for example, it is 00-00-00, which is not supported
                        // by .NET. So for now, we catch a cast exception and set it to DateTime.MinValue.
                        try {
                            dataField.Field.SetValue(value, DateTime.Parse(dataValue.ToString()));
                        }
                        catch {
                            dataField.Field.SetValue(value, DateTime.MinValue);
                        }
                    }
                    else
                    {
                        dataField.Field.SetValue(value, dataValue);
                    }
                }
            }

            return(value);
        }