Search code examples
c#connection-stringdappersqlexception

Dapper Exception - "The ConnectionString property has not been initialized" when 'buffered' is 'false'


I am trying out Dapper and I have stumbled upon this exception:

System.InvalidOperationException: The ConnectionString property has not been initialized.
...

Here is the code:

public IEnumerable<T> GetAll<T>(string sql, DynamicParameters parameters, string connectionString, CommandType commandType = CommandType.StoredProcedure)
{
    using IDbConnection db = new SqlConnection(connectionString);
    var result = db.Query<T>(sql, parameters, commandType: commandType, commandTimeout: COMMAND_TIMEOUT, buffered: false);
    return result;
}

When I remove the buffered parameter, everything works OK.

var result = db.Query<T>(sql, parameters, commandType: commandType, commandTimeout: COMMAND_TIMEOUT);

Solution

  • I suspect the real problem here is that you are returning an open queryable, which means you're leaving the scope of the using block and disposing the connection that is still being used. The real problem here is an object disposed too soon, but it is manifesting in an unusual way.

    Basically, you need to not dispose the connection until you're done with the data that needs the connection. A lazy way of doing this would be:

    using IDbConnection db = new SqlConnection(connectionString);
    foreach (var row in db.Query<T>(sql, parameters, commandType: commandType, commandTimeout: COMMAND_TIMEOUT, buffered: false)
    {
        yield return row;
    }
    

    This only happens when not buffering the data, because buffering means "get all the data before returning to the caller", instead of returning an open query. By switching to an "iterator block" (via yield return) the scope of the using is extended until the last of the data has been consumed (or the loop somehow else exited).