You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForms切换SQLite数据库后DataGridView仍显示旧数据求助

解决WinForms切换公司后DataGridView显示旧数据的问题

问题诊断

  1. 静态连接字符串固化:AccessToDatabaseComp中的dbPathcomp和conStringComp是静态字段,类加载时就固定了初始数据库路径,切换公司后不会重新计算,导致始终连接旧数据库。
  2. 静态SQLite连接未重置:静态sqlite连接实例一旦创建,切换数据库时不会销毁,仍然指向旧数据库文件。
  3. 连接管理逻辑错误:sqliteconComp方法中,如果连接已打开会直接关闭,后续操作会使用无效的关闭连接,导致数据读取异常。
  4. 查询条件逻辑矛盾:ViewSearch中的if (string.IsNullOrEmpty(search) && !string.IsNullOrEmpty(search))永远为假,空搜索时也会执行模糊查询逻辑。

解决方案

1. 重构数据访问类,移除静态依赖

修改数据访问类,每次获取连接时动态读取当前数据库路径,确保切换公司后连接新数据库:

public class AccessToDatabaseComp
{
    // 动态获取最新的连接字符串
    private static string GetConnectionString()
    {
        string dbPath = Application.StartupPath + "\\" + frmMain.Instance.lblDBFile.Text;
        return $"Data Source={dbPath};Version=3;";
    }

    private static SQLiteConnection _sqliteConn;

    public static SQLiteConnection GetConnection()
    {
        // 销毁旧连接,避免残留
        if (_sqliteConn != null)
        {
            if (_sqliteConn.State == ConnectionState.Open)
                _sqliteConn.Close();
            _sqliteConn.Dispose();
            _sqliteConn = null;
        }
        // 创建新连接并打开
        _sqliteConn = new SQLiteConnection(GetConnectionString());
        _sqliteConn.Open();
        return _sqliteConn;
    }

    // 重构retrieve方法,使用using管理连接
    public static DataSet Retrieve(string query)
    {
        try
        {
            using (var conn = GetConnection())
            {
                using (SQLiteDataAdapter adapter = new SQLiteDataAdapter(query, conn))
                {
                    DataSet ds = new DataSet();
                    adapter.Fill(ds);
                    return ds;
                }
            }
        }
        catch
        {
            return null;
        }
    }

    // 重构insert/update/delete方法,统一使用using管理连接
    public static bool Insert(string query)
    {
        try
        {
            using (var conn = GetConnection())
            {
                using (SQLiteCommand cmd = new SQLiteCommand(query, conn))
                {
                    int rows = cmd.ExecuteNonQuery();
                    return rows > 0;
                }
            }
        }
        catch
        {
            return false;
        }
    }

    // update和delete方法参照insert修改...
}

2. 修复ViewSearch方法的逻辑错误

修正矛盾的查询条件,统一数据加载逻辑:

private void ViewSearch(string search)
{
    try
    {
        string query = string.Empty;

        // 修正条件:空搜索执行全量查询,否则执行模糊查询
        if (string.IsNullOrEmpty(search))
        {
            query = "Select * from tblAccount";
        }
        else
        {
            query = "Select * from tblAccount where AccountName Like '%" + search + "%'";
        }

        // 加载新数据
        var ds = AccessToDatabaseComp.Retrieve(query);
        dgvAccountView.AutoGenerateColumns = false;

        if (ds != null && ds.Tables[0].Rows.Count > 0)
        {
            dgvAccountView.DataSource = ds.Tables[0];

            // 列配置保持不变
            dgvAccountView.Columns[0].HeaderText = "Account ID";
            dgvAccountView.Columns[0].Width = 50;
            dgvAccountView.Columns[0].DataPropertyName = "AccountID";
            dgvAccountView.Columns[0].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleLeft;

            dgvAccountView.Columns[1].HeaderText = "Account Name";
            dgvAccountView.Columns[1].Width = 500;
            dgvAccountView.Columns[1].DataPropertyName = "AccountName";
            dgvAccountView.Columns[1].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleLeft;

            dgvAccountView.Columns[2].HeaderText = "Credit";
            dgvAccountView.Columns[2].Width = 150;
            dgvAccountView.Columns[2].DataPropertyName = "Credit";
            dgvAccountView.Columns[2].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;

            dgvAccountView.Columns[3].HeaderText = "Debit";
            dgvAccountView.Columns[3].Width = 150;
            dgvAccountView.Columns[3].DataPropertyName = "Debit";
            dgvAccountView.Columns[3].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
        }
        else
        {
            dgvAccountView.DataSource = null;
        }
    }
    catch (Exception ex)
    {
        // 添加异常提示,方便排查问题
        MessageBox.Show($"加载数据失败:{ex.Message}");
    }
}

3. 切换公司时强制刷新数据

在切换公司的逻辑中,更新数据库文件名后立即调用ViewSearch刷新DataGridView:

// 示例:切换公司的方法
private void SwitchCompany(string newDbFileName)
{
    // 更新当前数据库文件名
    frmMain.Instance.lblDBFile.Text = newDbFileName;
    // 刷新账户模块数据
    ViewSearch(string.Empty);
}

额外优化建议

  • 防止SQL注入:当前模糊查询直接拼接字符串存在风险,改用参数化查询:
    // 在Retrieve方法中修改查询逻辑
    public static DataSet Retrieve(string search)
    {
        try
        {
            string query = string.IsNullOrEmpty(search) 
                ? "Select * from tblAccount" 
                : "Select * from tblAccount where AccountName Like @Search";
            
            using (var conn = GetConnection())
            {
                using (SQLiteCommand cmd = new SQLiteCommand(query, conn))
                {
                    if (!string.IsNullOrEmpty(search))
                    {
                        cmd.Parameters.AddWithValue("@Search", "%" + search + "%");
                    }
                    using (SQLiteDataAdapter adapter = new SQLiteDataAdapter(cmd))
                    {
                        DataSet ds = new DataSet();
                        adapter.Fill(ds);
                        return ds;
                    }
                }
            }
        }
        catch
        {
            return null;
        }
    }
    
  • 使用BindingSource管理数据源:通过BindingSource作为中间层,更方便数据刷新:
    private BindingSource _bs = new BindingSource();
    // 加载数据时
    _bs.DataSource = ds.Tables[0];
    dgvAccountView.DataSource = _bs;
    // 刷新时调用
    _bs.ResetBindings(false);
    

内容的提问来源于stack exchange,提问作者wasim khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 21:09:58