C# SQLite, database being left locked after a read

2020-04-20 03:31发布

问题:

I have read some of the related posts about this and didn't quite understand. What is happening is it appears that after this access to the database, the database is being left locked so that it can be read, but not written to. After exiting the application, the database is unlocked again. Can you look at it and talking to me like I am ignorant, point out the error of my way of handling this?

 public static Partner GetOnePartner(string code)
 {
    Partner partner = new Partner();
    SQLiteConnection connection = GroomwatchDB.GetConnection();
    string sqlStatement = "SELECT * FROM partners WHERE partner_code = @partner_code";

    SQLiteCommand command = new SQLiteCommand(sqlStatement, connection);
    command.Parameters.Add(new SQLiteParameter("@partner_code"));
    command.Parameters["@partner_code"].Value = code;

    try
    {
        connection.Open();
        SQLiteDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow);
        if(reader.Read())
        {
            partner.Code = reader["partner_code"].ToString();
            partner.Last_name = reader["last_name"].ToString();
            partner.First_name = reader["first_name"].ToString();
            partner.Pay_rate = (double)reader["pay_rate"];
            partner.Active = reader["active"].ToString();
        }
        else
        {
            partner.Code = code;
            partner.Last_name = "Not Found";
        }

    }
    catch (SQLiteException ex)
    {
       throw ex;
    }
    finally
    {
        connection.Close();
    }

    return partner;

} 

回答1:

You should correctly use your connection by using the IDisposable pattern.

In fact, every classes that implements the IDisposable interface needs to be call with a using. This ensure that the methods Dispose() is call, and so the unmanaged resources are being cleared (and you don't end with an open file) :

public static Partner GetOnePartner(string code)
 {
    Partner partner = new Partner();
    string sqlStatement = "SELECT * FROM partners WHERE partner_code = @partner_code";
    using(SQLiteConnection connection = GroomwatchDB.GetConnection())
    using(SQLiteCommand command = new SQLiteCommand(sqlStatement, connection))
    {
        command.Parameters.Add(new SQLiteParameter("@partner_code"));
        command.Parameters["@partner_code"].Value = code;
        connection.Open();
        using(SQLiteDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow))
        {
            if(reader.Read())
            {
                partner.Code = reader["partner_code"].ToString();
                partner.Last_name = reader["last_name"].ToString();
                partner.First_name = reader["first_name"].ToString();
                partner.Pay_rate = (double)reader["pay_rate"];
                partner.Active = reader["active"].ToString();
            }
            else
            {
                partner.Code = code;
                partner.Last_name = "Not Found";
            }
        }
    }
    return partner;
} 

References :

  • Proper use of the IDisposable interface
  • Do I have to Dispose the SQLiteCommand objects?
  • SqlConnection SqlCommand SqlDataReader IDisposable


标签: c# sqlite locked