SubSonic: MySqlDataReader closes connection
I am using SubSonic 2.1 and entcountered a problem while executing a Transaction with
SharedDbConnectionScope and TransactionScope. The problem is that in the obj.Save() method I get an "The connection must be valid and open" exception
I tracked down the problem to this line:
// Loads a SubSonic ActiveRecord object
User user = new User(User.Columns.Username, "John Doe");
in this Constructor of the User class a method "LoadParam" is called which eventually does
if (rdr != null)
rdr.Close();
It 开发者_StackOverflow中文版looks like the rdr.Close() implicitly closes my connection which is fine when using the AutomaticConnection. But during a transaction it is usally not a good idea to close the connection :-)
My Question is if this is by design or if it's an error in the MySqlDataReader.
That was tricky! After a bit debugging I found the following method in the SubSonic2 MySqlDataReader.cs file:
public override IDataReader GetReader(QueryCommand qry)
{
AutomaticConnectionScope conn = new AutomaticConnectionScope(this);
...
cmd.Connection = (MySqlConnection)conn.Connection;
IDataReader rdr;
try
{
rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch(MySqlException x)
{
conn.Dispose();
throw x;
}
...
}
Which is wrong since I am using a SharedDbConnection. In the SqlDataProvider it has been fixed already but not for MySqlDataReader.
It should look like this:
try
{
// if it is a shared connection, we shouldn't be telling the reader to close it when it is done
rdr = conn .IsUsingSharedConnection ?
cmd.ExecuteReader() :
cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (MySqlException)
{
// AutoConnectionScope will figure out what to do with the connection
conn.Dispose();
//rethrow retaining stack trace.
throw;
}
Pretty heavy bug, it rendered Querying in a Transaction impossible (I must admit I never needed this before).
精彩评论