/// <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); }