/// <summary> /// Execute the query and return the results in a list of type <paramref name="T"/>. In case there are one-to-many joined tables, /// there may be duplicates of the same root entity of type <typeparamref name="T" />. /// </summary> /// <param name='con'> /// The IDbConnection on which the query will be executed. /// </param> /// <typeparam name='T'> /// The type of each result. /// </typeparam> public List <T> List <T>(IDbConnection con) where T : new() { // We can't do magic here. If two equally named columns from different tables are queried, the user is going to be in // trouble.. var allProjections = selectedProjections.ToDictionary(p => p.GetName(), p => p.GetName()); var resultsFetcher = new ResultsFetcher <T>(allProjections); using (IDbCommand com = ToSqlCommand(con)) { return(resultsFetcher.List(com)); } /* * // Get the fields and properties of type T and put their setter methods in the cache, if not already there * IDictionary<string, SetValue> setters = CachedTypeData.FetchSettersOf<T>(); * * // Execute the SQL command and create the list * List<T> results = new List<T>(10); * using (IDbCommand com = this.ToSqlCommand(con)) * { * using (IDataReader dr = com.ExecuteReader()) * { * while (dr.Read()) * { * T temp = new T(); * * // Get the setters in the same order of the columns in selectColumns to set the fields/properties accordingly * int i = 0; * foreach (ProjectionFragment proj in selectedProjections) * { * SetValue setter; * * // GetName() should return the correct property name, no matter if it is an aliased expression or a column * string propertyName = proj.GetName(); * * try * { * setter = setters[propertyName]; * } * catch (KeyNotFoundException) * { * //Console.WriteLine("Property named {0} not defined in {1}", propertyName, typeof(T).ToString()); * i++; * continue; * } * catch (IndexOutOfRangeException) * { * throw new Exception("No field or property in the result type named " + propertyName + " exists."); * } * * try * { * // Check for nulls * //Console.WriteLine("SETTING value of {0} to {1}", propertyName, dr[i]); * if (dr.IsDBNull(i)) * { * setter(temp, null); * } * else * { * setter(temp, dr[i]); * } * * i++; * } * catch (IndexOutOfRangeException) * { * throw new Exception("One of the selected columns does not exist in the database. Maybe there is a typo in the selected columns?"); * } * } * * results.Add(temp); * } * } * } * * return results; */ }