tags:

views:

47

answers:

1

I have this method:

 public static IEnumerable<T> ExecuteReaderSp<T>(string sp, string cs, object parameters) where T : new()
    {
        using (var conn = new SqlConnection(cs))
        {
            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = sp;
                cmd.InjectFrom<SetParamsValues>(parameters);
                conn.Open();
                using (var dr = cmd.ExecuteReader())
                    while (dr.Read())
                    {
                        var o = new T();
                        o.InjectFrom<ReaderInjection>(dr);
                        yield return o;
                    }
            }
        }
    }

I had the situation when I called it to times (with different T and sp) inside a "transaction scope"

and if I wasn't calling .ToArray() on the fist call than I had an error that was telling me that this Command is already associated with another DataReader and that the first one should be closed first

+3  A: 

Since it's in a transaction scope, I'm sure that ADO.Net is providing the same physical connection to the database, but I think the text this Command is already associated is a red herring - try adding MultipleActiveResultSets=True to your connection string.

The situation you're running into here is functions with yield return aren't fully evaluated until the IEnumerable objects are fully walked - and SqlConnections, by default, only allow one DataReader to be active against them at a time.

Also, I applaud your proper use of using statements - but be aware that nothing will get Disposed until you walk the entire IEnumerable. (This is what ToArray() is doing for you to make it all work.)

mattdekrey