When I find a new idea, I always stick with it, and am unable to see any weak sides of it. Bad things happen when I start to use the new idea in a large project, and discover some moths later that the idea was extremely bad and I shouldn't use it in any project.
That's why, having a new idea and being ready to use it in a new large project, I need your opinion on it, especially negative one.
For a long time, I was bored to type again and again or copy-paste the following blocks in projects where database must be accessed directly:
string connectionString = Settings.RetrieveConnectionString(Database.MainSqlDatabase);
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
    sqlConnection.Open();
    using (SqlCommand getProductQuantities = new SqlCommand("select ProductId, AvailableQuantity from Shop.Product where ShopId = @shopId", sqlConnection))
    {
        getProductQuantities.Parameters.AddWithValue("@shopId", this.Shop.Id);
        using (SqlDataReader dataReader = getProductQuantities.ExecuteReader())
        {
            while (dataReader.Read())
            {
                yield return new Tuple<int, int>((int)dataReader["ProductId"], Convert.ToInt32(dataReader["AvailableQuantity"]));
            }
        }
    }
}
So I've done a small class which allows to write something like that to do the same thing as above:
IEnumerable<Tuple<int, int>> quantities = DataAccess<Tuple<int, int>>.ReadManyRows(
    "select ProductId, AvailableQuantity from Shop.Product where ShopId = @shopId",
    new Dictionary<string, object> { { "@shopId", this.Shop.Id } },
    new DataAccess<string>.Yield(
        dataReader =>
        {
            return new Tuple<int, int>(
                (int)dataReader["ProductId"],
                Convert.ToInt32(dataReader["AvailableQuantity"]);
        }));
The second approach is:
- Shorter to write, 
- Easier to read (at least for me; some people may say that actually, it's much less readable), 
- Harder to make errors (for example in first case, I often forget to open the connection before using it, or I forget - whileblock, etc.),
- Faster with the help of Intellisense, 
- Much more condensed, especially for simple requests. 
Example:
IEnumerable<string> productNames = DataAccess<string>.ReadManyRows(
    "select distinct ProductName from Shop.Product",
    new DataAccess<string>.Yield(dataReader => { return (string)dataReader["ProductName"]; }));
After implementing such thing with simple ExecuteNonQuery, ExecuteScalar and ReadManyRows and a generic DataAccess<T>.ReadManyRows in a small project, I was happy to see that the code is much shorter and easier to maintain.
I found only two drawbacks:
- Some modifications in requirements will require heavy code changes. For example, if there is a need to add transactions, it will be very easy to do with ordinary - SqlCommandapproach. If my approach is used instead, it will require to rewrite the whole project to use- SqlCommands and transactions.
- Slight modifications on command level will require to move from my approach to standard - SqlCommands. For example, when querying one row only, either- DataAccessclass must be extended to include this case, or the code must use directly- SqlCommandwith- ExecuteReader(CommandBehavior.SingleRow)instead.
- There might be a small performance loss (I don't have precise metrics yet). 
What are the other weak points of this approach, especially for DataAccess<T>.ReadManyRows?
 
     
     
     
     
     
    