Will ExecuteReader(CommandBehavior.CloseConnection) always close connection?

后端 未结 5 939
栀梦
栀梦 2021-01-11 14:27

Is it safe to write this helper method like this? Will it always close the connection? I understend if all goes well, it will, but will ExecuteReader close the connection ev

相关标签:
5条回答
  • 2021-01-11 14:59

    If you close the reader and/or wrap the reader with using(var reader ...){} block YES you ensure that your connection is closed.

    Not wrapping and doesn't closing the reader with reader.Close() kept my connection open.

    0 讨论(0)
  • 2021-01-11 15:02

    Yes it will (inside a using block like you're doing). But to access the data you probably want to use While DbDataReader.read instead of iterating over its contents.

    0 讨论(0)
  • 2021-01-11 15:06

    I know the question is related to closing the connection which will be the case; however, the connection won't be disposed. To dispose the connection itself, you need to enclose it a using block as well:

    using (DBConnection conn = new ...)
    {
        using (DbCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = commandText;
            conn.Open();
            using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
            {
                foreach (DbDataRecord record in reader) { yield return record; }
            }
        }
    }
    

    UPDATE I thought this was an interesting question so I wrote the following test:

    string connString = @"Data Source=.\SQLEXPRESS;Initial Catalog=msdb;Integrated Security=True;";
    SqlConnection conn = new SqlConnection(connString);
    
    try
    {
    using (SqlCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = "select  from MSdbms"; 
            conn.Open();
            Console.WriteLine(conn.State);
            using (IDataReader reader = cmd.ExecuteReader())//Will throw an exception - Invalid SQL syntax -see setting CommandText above
            {
                Console.WriteLine("here");
            }
        }
    }
    catch(Exception ex)
    {  Console.WriteLine(conn.State); } //prints Open
    

    If the line using (IDataReader reader = cmd.ExecuteReader()) is changed to: using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) then it prints Closed. Something to keep in mind.

    0 讨论(0)
  • 2021-01-11 15:21

    Yes even if it throws an exception it will close the connection. If you do not specify CommandBehavior.CloseConnection and you close the connection, your calling code cannot access the contents of the reader.

    Also from MSDN:

    When the command is executed, the associated Connection object is closed when the associated DataReader object is closed.

    You should ensure that the reader is closed when you are done with it. The nice thing about all of this is you've got it wrapped around a using statement and you aren't using try/catch/finally in this case the reader will be closed which then will close the database connection.

    0 讨论(0)
  • 2021-01-11 15:23

    Personally I prefer a using clause statement to close/dispose the connection , simply for parallel construction reasons - same as in good English Grammar.
    From my point of view using the CommandBehavior is not balanced and therefore unpredictable.

    I constantly tell to my developers to go simple and consistent.
    As if they forget to set the CommandBehavior...

    I won't see it...
    but if they don't use a using statement...
    I will see it as it is very important.

    0 讨论(0)
提交回复
热议问题