I've been trying to get this method to work since yesterday and have taken to pulling my hair out -
Basically, I have a method that retrieves articles from a database. Below is the method code:
public static IEnumerable<Article> RetrieveTopTenArticles()
{
using(var dbConn = new SqlConnection(Settings.Instance.DbConnectionString))
{
const String query = "SELECT TOP 10 Title, Content FROM Article";
Func<SqlDataReader, Article> operation = reader => reader.ToArticle();
return dbConn.SqlRetrieveMultiple(query, operation);
}
}
And in a separate "Extensions" class -
public static IEnumerable<T> SqlRetrieveMultiple<T>(this SqlConnection sqlConnection, String query, Func<SqlDataReader, T> operation, params SqlParameter[] parameters)
{
sqlConnection.Open();
using (var command = new SqlCommand(query, sqlConnection))
{
if (parameters.Length > 0)
{
command.Parameters.AddRange(parameters);
}
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
yield return operation.Invoke(reader);
}
}
}
}
As you can see, I have an extension method that performs a SQL select statement, and iterates over the results, invoking the operation and converting each SqlDataReader row into my Article type (also done with an extension method). I believe I've used this same exact extension method in the past with no issues.
When I debug this and it gets to the dbConn.SqlRetrieveMultiple(query, operation); row, if I hit F11 to step into, it steps over the row completely. It continues to walk down the chain of ending nested brackets and eventually I get an exception on the sqlConnection.Open().
The exception I get is:
The ConnectionString property has not been initialized.
I have found that the function will step into just fine if I remove my Func delegate. I feel like this has to be something stupid / unrelated to extension methods or SqlConnection because I get the same behavior if I put it in a regular private static method within the same class. If I turn on .NET framework source stepping at the sqlConnection.Open(); line, it jumps into a ctor method of the .NET framework... I can post up more code if requested but I think I've got everything necessary. Please let me know if you've got any ideas.