Управление доступом к данным в простом приложении WinForms - PullRequest
0 голосов
/ 25 декабря 2010

У меня есть простое приложение для ввода данных WinForms, которое использует SQLite.Это всегда будет однопользовательское приложение и всегда с локальной базой данных.У меня есть несколько вкладок, с UserControls, служащих в качестве содержимого для вкладок.Каждый раз, когда выбирается вкладка, соответствующий UserControl инициализируется, а старый удаляется (с помощью TabPage.Controls.Remove).

Каждый UserControl инициализирует общий объект DataAccess, который охватывает все компоненты базы данных и может быть повторно использован с любым содержимым вкладок.Проблема в том, что у меня есть открытый SQLiteConnection на время жизни вкладки (UserControl).Я читал в другом месте, что это не очень хорошая практика.Я не хочу переусердствовать в разработке со сложными слоями данных и слоями бизнес-объектов, отчасти потому, что я не знаю, как это сделать, а отчасти потому, что я не думаю, что это необходимо для этого приложения.

Я в основном сохраняю в памяти те же объекты подключения, адаптера, DataTable, SqlCommand и т. Д. И просто повторно использую их с различными параметрами запроса SQL, а также для получения этих кэшированных данных другими методами (например, RowCount).У меня была проблема с методом LoadData, так как он не удалял результаты предыдущих запросов из DataTable, поэтому я делаю это вручную в начале.

Я пытался найти способ использовать «использование» с SQLiteConnection и другими объектами, но тогда мне пришлось бы переделывать весь материал DataLoad или аналогичный для простых вещей, таких как RowCount.Поэтому я просто ищу предложения и комментарии по этому подходу с доступом к данным.

Ниже приведен мой класс DataAccess.

public class DataAccess
{
    private SQLiteConnection connection = new SQLiteConnection(Global.DbConnectionString);
    private DataTable dataTable = new DataTable();
    private SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter();
    private SQLiteCommandBuilder commandBuilder = new SQLiteCommandBuilder();
    private SQLiteCommand command = new SQLiteCommand();
    private BindingSource bindingSource = new BindingSource();


    public DataAccess()
    {
        dataAdapter.SelectCommand = command;
        commandBuilder.DataAdapter = dataAdapter;
        bindingSource.DataSource = dataTable;
    }

    ~DataAccess()
    {
        connection.Dispose();
    }

    public BindingSource BindingSource
    {
        get { return bindingSource; }
    }


    ///*
    public void LoadData(string sql, Dictionary<string, string> parameters)
    {
        try
        {
            dataTable.Clear();
            command.Connection = connection;

            // Ignore sql parameter if we already have CommandText. This assumes sql never changes per instance
            if (command.CommandText == null)
                command.CommandText = sql;

            foreach (KeyValuePair<string, string> parameter in parameters)
            {
                if (command.Parameters.Contains(parameter.Key))
                    command.Parameters[parameter.Key].Value = parameter.Value;
                else
                {
                    command.Parameters.Add(new SQLiteParameter(parameter.Key));
                    command.Parameters[parameter.Key].Value = parameter.Value;
                }
            }
            dataAdapter.Fill(dataTable);

        }
        catch (SqlException)
        {
            MessageBox.Show("Data Problem, need to display what's wrong later");
        }

    }//*/

    public int RowCount()
    {
        return dataTable.Rows.Count;
    }

    public string GetFieldValue(int row_index, string column_name)
    {
        return dataTable.Rows[row_index][column_name].ToString();
    }

    public void Save()
    {
        dataAdapter.Update(dataTable);
    }

    public void NewRow(Dictionary<string, string> fields)
    {
       DataRow dataRow = dataTable.NewRow();

        foreach (KeyValuePair<string, string> field in fields)
            dataRow[field.Key] = field.Value;

        dataTable.Rows.Add(dataRow);
    }
}

1 Ответ

1 голос
/ 25 декабря 2010

Если вы хотите сделать это красиво, вы должны создать слой доступа к данным, который предоставит методы для извлечения данных и их изменения. Этот слой будет открывать соединение всякий раз, когда это необходимо, а затем закрывать его. Вы можете добавить кеширующий слой поверх него. И ваш графический интерфейс будет использовать только объекты данных из нижних уровней.

Это не маленькая переписка, поэтому, если ваше текущее решение работает, и вы не хотите прилагать к нему много усилий, просто оставьте это так, это не так уж плохо. Если это простая программа, то это простое решение просто отлично.

...