/// <summary> /// Generates instance of the model with the data read from DB /// </summary> /// <param name="reader">NpgsqlDataReader to read data from DB</param> /// <param name="type">The type from which create instance</param> /// <param name="ignore_user">If the sp don't return a user, but the type has a User property set as true</param> /// <returns></returns> private object GetParametersFromReader(NpgsqlDataReader reader, Type type, bool ignore_user) { var instance = Activator.CreateInstance(type); foreach (var prop in type.GetProperties()) //Run over all the properties of the recieved entity { if (ignore_user && prop.PropertyType == typeof(User)) //In case that the sp don't return the user details and one of the properties is indeed User { continue; //Continue to the next prop } if (prop.PropertyType.GetInterfaces().Contains(typeof(IPoco))) //Check if the property is implementing the IPoco interface { var instance_prop = GetParametersFromReader(reader, prop.PropertyType, ignore_user); //Recursion prop.SetValue(instance, instance_prop); //After recursion ends set the prop value to the value that was read continue; //Continue to the next prop } string column_name = prop.Name;//Set the column name to read as the property name var custom_attr_column_name = (ColumnAttribute[])prop.GetCustomAttributes(typeof(ColumnAttribute), true); //Get all column attributes of the property if (custom_attr_column_name.Length > 0) //If there is at least one attribute (in this program there won't be 2 column attributes on same prop) { column_name = custom_attr_column_name[0].Name; //Set the column name as the column attribute value } if (prop.PropertyType == typeof(string)) //Check if property is a string (some of the strings might be nulls); { var value = reader.GetSafeString(reader.GetOrdinal(column_name)); //Get the string safely, if there is not string return null prop.SetValue(instance, value); //Set the prop value as the value that was read (might be null) } else { var value = reader[column_name]; //Get the value from DB prop.SetValue(instance, value); //Set the prop value as the value that was read } } return(instance); }