Managing a SQLite Database Connection When the application connects to the database it keeps the connection open until the user closes the file using File->Close.

Is this bad practice?

Should I be opening and closing the connection every time I need to use it?

using System.Data;
using System.Data.SQLite;
using System.IO;
using System.Windows.Forms;

namespace timelord
{
    /// &lt;summary&gt;
    /// Manages the tasks database
    /// &lt;/summary&gt;
    class Timesheet
    {
        private string filePath;
        private SQLiteConnection sqlite;
        private SQLiteDataAdapter adapter;
        private SQLiteCommandBuilder builder;
        private DataTable datatable;

        /// &lt;summary&gt;
        /// Creates a timesheet object that determines if the filepath exists.
        /// If the filepath exists then it opens a database.
        /// If it does not exist it creates a database.
        /// &lt;/summary&gt;
        /// &lt;param name="filePath"&gt;The path to open or create a database file at.&lt;/param&gt;
        public Timesheet(string filePath)
        {
            this.filePath = filePath;

            if (File.Exists(filePath))
            {
                openDatabase();

            }else
            {
                createDatabase();

                createSchema();
            }

            prepareQueries();

            this.datatable = new DataTable();

            this.adapter.Fill(this.datatable);
        }

        /// &lt;summary&gt;
        /// Calls the methods that create the database file, connection, and schema
        /// &lt;/summary&gt;
        private void createDatabase()
        {
            SQLiteConnection.CreateFile(filePath);

            openDatabase();
        }

        /// &lt;summary&gt;
        /// Creates the database connection
        /// &lt;/summary&gt;
        private void openDatabase()
        {
            sqlite = new SQLiteConnection("Data Source=" + this.filePath + ";Version=3;");
            try
            {
                sqlite.Open();
            }
            catch(SQLiteException e)
            {
                MessageBox.Show(e.Message);
            }
        }

        /// &lt;summary&gt;
        /// Creates the schema for all tables nessicary
        /// &lt;/summary&gt;
        private void createSchema()
        {
            string query = "CREATE TABLE task (id INTEGER PRIMARY KEY AUTOINCREMENT, description TEXT, begindate TEXT, enddate TEXT, status INTEGER default 0)";

            SQLiteCommand cmd = new SQLiteCommand(query, sqlite);

            cmd.ExecuteNonQuery();

        }

        /// &lt;summary&gt;
        /// Prepares the queries used to manipulate the timesheet
        /// &lt;/summary&gt;
        private void prepareQueries()
        {
            adapter = new SQLiteDataAdapter("select id,description,begindate,enddate,status from task", sqlite);

            builder = new SQLiteCommandBuilder(adapter);

            adapter.UpdateCommand = builder.GetUpdateCommand();
            adapter.DeleteCommand = builder.GetDeleteCommand();
            adapter.InsertCommand = builder.GetInsertCommand();
        }

        /// &lt;summary&gt;
        /// Return the task table
        /// &lt;/summary&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        public DataTable Tasks()
        {
            return this.datatable;
        }

        public void Update()
        {
            adapter.Update(datatable);

            datatable.Clear();

            adapter.Fill(datatable);
        }

        /// &lt;summary&gt;
        /// Closes the database connection
        /// &lt;/summary&gt;
        public void close()
        {
            sqlite.Close();
        }
    }
}
You don't need to create the database file if it doesn't exist, the SQLite driver will take care of it; to ensure your table does not exist on creation, you can just add IF NOT EXISTS to the query.

I would also close the connection every time, this has already been covered by other answers. In addition I would make the class stateless as it doesn't need a state if we open/close the connection every time (Being stateless brings a lot of other advantages).

I would also remove any logic from the constructor, to do this you will need a state or you will have to check on every command unfortunately so I left it to you.

Here is my 0.02:

internal class Timesheet
{
    private const string SelectTaskQuery = "SELECT id, description, begindate, enddate, status FROM task";

    private readonly string _filePath;

    public Timesheet(string filePath)
    {
        _filePath = filePath;

        InitializeDb();
    }

    private DataTable Tasks() =&gt; ExecuteWithConnection(Tasks);

    private void InitializeDb() =&gt; ExecuteWithConnection(connection =&gt;
    {
        using (var command = connection.CreateCommand())
            CreateSchemaIfNotExists(command);
    });

    private SQLiteConnection GetConnection() =&gt; new SQLiteConnection("Data Source=" + _filePath + ";Version=3;");

    private void ExecuteWithConnection(Action&lt;SQLiteConnection&gt; action)
    {
        using (var connection = GetConnection())
        {
            connection.Open();

            action(connection);
        }
    }

    private T ExecuteWithConnection&lt;T&gt;(Func&lt;SQLiteConnection, T&gt; action)
    {
        using (var connection = GetConnection())
        {
            connection.Open();

            return action(connection);
        }
    }

    private static DataTable Tasks(SQLiteConnection connection)
    {
        var adapter = new SQLiteDataAdapter(SelectTaskQuery, connection);

        var datatable = new DataTable();

        adapter.Fill(datatable);

        return datatable;
    }

    public void Update(DataTable dataTable)
    {
        ExecuteWithConnection(connection =&gt;
        {
            var adapter = new SQLiteDataAdapter(SelectTaskQuery, connection);

            var builder = new SQLiteCommandBuilder(adapter);

            adapter.Update(dataTable);
        });
    }

    private static void CreateSchemaIfNotExists(IDbCommand command)
    {
        const string query = "CREATE TABLE IF NOT EXISTS task (id INTEGER PRIMARY KEY AUTOINCREMENT, description TEXT, begindate TEXT, enddate TEXT, status INTEGER default 0)";

        command.CommandText = query;

        command.ExecuteNonQuery();
    }
}


I would also add a small ORM like Dapper and add statically typed entities for insert/update.