Se vuoi fare una classe generale, puoi farlo. Basta che incapsuli il comportamento del codice che hai postato in una classe (magari astratta) che implementa le funzionalità base di connessione con un database.
Ad esempio, potresti rappresentare tutti gli attributi con un dizionario: le query verrebbero costruite basandosi sul dizionario di attributi piuttosto che sulle proprietà della classe. Potresti inoltre scrivere una funzione generica che, usando la reflection, inizializzi un qualsiasi tipo di oggetto partendo da una query:
codice:
public static IEnumerable<T> GetResultObjects<T>(String query) where T : new
{
    List<Dictionary<String, Object>> queryResults = ExecuteQuery(query);

    foreach(Dictionary<String, Object> record in queryResults)
    {
        T result = new T();
        foreach(PropertyInfo property in typeof(T).GetProperties())
           if (property.CanWrite && queryResult.ContainsKey(property.Name))
              property.SetValue(result, Convert.ChangeType(queryResult[property.Name], property.PropertyType);
        yield return result;
    }
}
Tuttavia la reflection non è il massimo per le prestazioni... (né tanto meno forzare tutte quelle conversioni da Object).