• TreeView的数据源绑定—采用sqlite作为数据源,实现对treeview控件进行增删改查


        接上篇TreeView的数据源绑定—采用XML作为数据源,实现对treeview进行增删改查,之后回写XML文档,本篇是使用一种比较轻型的数据库—sqlite作为treeview的数据源,关于sqlite具体的知识请前往:

        1,sqlite官网

        2,维基百科

        3,百度百科

        根据当前项目存储的要求,由于之前使用XML来存储,现在再用XML有些不方便,时间上花费要多,所以在网上找了sqlite作为新的数据存储源,使用之后,感觉实在是太方便了,所以把使用过程记录下来,本人作为第一次用sqlite,对以前没接触过sqlite的朋友来说,可以参考参考的,但毕竟是我一个人的思想,所以,写的不好,还请大家不要见怪!

        首先,得先讲下sqlite的优点:使用简单,不需要安装配置,拿到.db文件就可以用,蒽,很适合存储量比较小的winfrom程序(如我当前的这个项目),最重要的是sqlite开源而还且免费的哦,还有其他很多的优点,现在讲到的都是我现在已经用到了;

        当然,毕竟没有完美的事物,缺点:存储的数据量不大,大家用的时候不要当作MSSQL、MYSQL或ORACLE来用,据说,最大可以达到2TB,不知道是不是真的。- -!性能嘛,当然是数据量越小的时候,发挥的越好,反正我用到现在查询速度还是可以的,够用就行了。

        使用的时候装个管理工具吧,我推荐我现在使用的这款,是免费的,SQLite可视化数据库管理器

        在项目中还需要引用来自外部的2个DLL文件,我把文件放在了附件中。

        使用sqlite的时候,我的项目中新建了一个类,该类专门处理来自窗体页面的查询,类似与SQLHelper,我把主要的查询函数贴上来,具体的我会作为附件,请需要的朋友下载附件查看。

    创建SQL语句和插入SQL语句
            /// <summary>
    /// 创建SQL语句和插入SQL语句
    /// </summary>
    /// <param name="sqlStr">SQL语句</param>
    public void ExecuteCreate(string sqlStr)
    {
    using (DbConnection conn = new SQLiteConnection(connectionString))
    {
    conn.Open();
    DbCommand comm = conn.CreateCommand();
    comm.CommandText = sqlStr;
    comm.CommandType = CommandType.Text;
    comm.ExecuteNonQuery();
    }
    }
    执行查询
            /// <summary>
    /// 执行查询
    /// </summary>
    /// <param name="sqlStr">SQL语句</param>
    public string ExecQuery(string sqlStr)
    {
    string text = string.Empty;
    using (DbConnection conn = new SQLiteConnection(connectionString))
    {

    conn.Open();
    DbCommand comm = conn.CreateCommand();
    comm.CommandText = sqlStr;
    comm.CommandType = CommandType.Text;

    using (IDataReader reader = comm.ExecuteReader())
    {
    while (reader.Read())
    {
    text = reader[0].ToString();
    }
    }
    }

    return text;
    }
    修改数据库的语句
            /// <summary>
    /// 修改数据库的语句
    /// </summary>
    /// <param name="strSql">需要修改SQL语句</param>
    public void ExecuteModity(string strSql)
    {
    using (DbConnection conn = new SQLiteConnection(connectionString))
    {
    conn.Open();
    DbCommand comm = conn.CreateCommand();
    comm.CommandText = strSql;
    comm.CommandType = CommandType.Text;
    comm.ExecuteNonQuery();
    }
    }
    删除数据库中的数据
            /// <summary>
    /// 删除数据库中的数据
    /// </summary>
    /// <param name="strSql"></param>
    public void ExecuteRemove(string strSql)
    {
    using (DbConnection conn = new SQLiteConnection(connectionString))
    {
    conn.Open();
    DbCommand comm = conn.CreateCommand();
    comm.CommandText = strSql;
    comm.CommandType = CommandType.Text;
    comm.ExecuteNonQuery();
    }
    }
    执行查询返回DataSet
            /// <summary>
    /// 执行查询返回DataSet
    /// </summary>
    /// <param name="sqlStr">SQL语句</param>
    /// <returns>返回DataSet</returns>
    public DataSet ExecDataSet(string sqlStr)
    {
    using (SQLiteConnection conn = new SQLiteConnection(connectionString))
    {
    conn.Open();
    SQLiteCommand cmd = conn.CreateCommand();
    cmd.CommandText = sqlStr;
    cmd.CommandType = CommandType.Text;

    DataSet ds = new DataSet();
    SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);

    da.Fill(ds);

    return ds;
    //conn.Close();
    }
    }

        查询sqlite的数据,然后绑定到treeview控件

    绑定sqlite的数据到treeview控件
            /// <summary>
    /// 绑定sqlite的数据
    /// </summary>
    private void SelectData()
    {
    string dbPath = "Area_db.db";
    SqliteHelper sh = new SqliteHelper(dbPath);
    //string sql = "select * from AreaTree";
    AddTreeView(0, (TreeNode)null);

    }


    private void AddTreeView(int parentId, TreeNode parentNode)
    {
    try
    {
    string strPath = "Area_db.db";
    string sql = "select * from AreaTree";
    SqliteHelper sh = new SqliteHelper(strPath);
    DataView dv = new DataView(sh.ExecDataSet(sql).Tables[0]);
    string strFile = "a_Parent=" + parentId;
    dv.RowFilter = strFile;

    foreach (DataRowView row in dv)
    {
    TreeNode node = new TreeNode();
    //处理根节点
    if (parentId == 0)
    {
    node.Name = row["a_Id"].ToString();
    node.Text = row["a_Name"].ToString();
    tree_Area.Nodes.Add(node);

    AddTreeView(Int32.Parse(row["a_Id"].ToString().Trim()), node);
    }
    //处理子节点
    else
    {
    node.Name = row["a_Id"].ToString();
    node.Text = row["a_Name"].ToString();
    parentNode.Nodes.Add(node);

    AddTreeView(Int32.Parse(row["a_Id"].ToString().Trim()), node);
    }
    }
    tree_Area.ExpandAll();
    }
    catch { }
    }

        修改treeview结构,保存到sqlite,这几个函数和使用MSSQL是一样的,和ADO.NET很像,所以这里也就直接贴出代码了,欢迎私下讨论。

    修改节点,保存数据
            private void ModifyTreeView()
    {
    try
    {
    string dbPath = "Area_db.db";
    string strAreaName = txt_AreaName.Text.Trim();
    string strNub = txt_Nub.Text.Trim();
    SqliteHelper sh = new SqliteHelper(dbPath);
    string sql = string.Empty;
    if (TextBoxValidator(strAreaName))
    {
    MessageBox.Show("请输入地区或设备名称 !", "提示");
    txt_AreaName.Focus();
    }
    else if (TextBoxValidator(strNub))
    {
    MessageBox.Show("请输入该地区或设备的逻辑地址 !", "提示");
    txt_Nub.Focus();
    }
    else
    {
    sql = "update AreaTree set a_Name='" + strAreaName + "',a_Value='" + strNub + "' where a_Id=" + tree_Area.SelectedNode.Name + "";
    sh.ExecuteModity(sql);
    tree_Area.Nodes.Clear();
    AddTreeView(0, (TreeNode)null);

    }
    }
    catch { }

    }

        删除节点,这里有个情况,如果删除多个,就是删除的节点中还有子节点的话,该如何操作,是把当前选中节点全部删掉,还是让用户只删除一个,这就看个人的需求了,我项目中的是只让客户删除不超过2级的节点。

       

    View Code
            private void RemoveTreeView()
    {
    if (tree_Area.SelectedNode != null)
    {
    TreeNode node = tree_Area.SelectedNode;
    int childNode = node.Nodes.Count;


    if (childNode == 0)
    {
    DeleteTreeNode(node);
    }
    else
    {
    if (MessageBox.Show("确定要删除选中的所有节点吗 ?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
    {
    DeleteTreeNode(node);
    }
    }
    }
    else
    {
    MessageBox.Show("未选中节点,请选中需要删除的节点!", "提示");
    }
    }


    /// <summary>
    /// 删除所选节点及其子节点,同时更新数据库
    /// </summary>
    /// <param name="parentNode"></param>
    private void DeleteTreeNode(TreeNode parentNode)
    {
    try
    {
    //获取当前删除的节点是否还有子节点
    int childCount = parentNode.Nodes.Count;

    for (int i = 0; i < childCount; i++)
    {
    TreeNode childNode = parentNode.Nodes[0];
    if (childNode.Nodes.Count > 0)
    {
    DeleteTreeNode(childNode);
    }
    else
    {
    DeleteTreeNode(childNode);
    childNode.Remove();
    }
    }
    if (parentNode.Nodes.Count == 0)
    {
    DeleteNodeData(parentNode);
    parentNode.Remove();
    }
    }
    catch { }
    }

    /// <summary>
    /// 在数据库中删除当前选中的节点
    /// </summary>
    /// <param name="node"></param>
    private void DeleteNodeData(TreeNode node)
    {
    string strPath = "Area_db.db";
    SqliteHelper sh = new SqliteHelper(strPath);
    string sql = string.Empty;
    sql = "delete from AreaTree where a_Id="+node.Name+"";
    sh.ExecuteRemove(sql);
    }


        蒽,还有个情况是,关于sqlite管理器的字符编码问题,在sqlite管理器中一般都以UFT-8编码显示,但是在C#中,所有字符窜的编码都是unicode,写入的时候应该注意编码转换问题,我这边是出现了字符编码的问题,后面写了个函数来转换。在连接sqlite的时候可以写明需要操作的是什么编码,编译环境会自动根据设定的字符编码来get、set,显示也就正常了,如果,在sqlite管理工具上查看的是uft-8编码的话,那取出的数据也应该是显示正常的,但是在有的PC上显示的是乱码,这个时候就应该去转换一下,读取的数据了。

             /// <summary>
    /// 把GB转换成uft8-8
    /// </summary>
    /// <param name="strEnCode"></param>
    private string EnCodeing(string strEnCode)
    {
    UTF8Encoding uft8 = new UTF8Encoding();
    string unicodeString = strEnCode;
    Byte[] encodeBytes = uft8.GetBytes(unicodeString);
    String decodeString = uft8.GetString(encodeBytes);
    return decodeString;
    }

        程序运行效果图:

        总结:我这边写的数据库语句全是拼接的,但是在逛论坛的时候,看到说数据库的语句要少用字符窜拼接的形式,但是,我不知道该怎么去解决他,所以,还请各位知道的前辈告知下,谢谢!这次的sqlite学习旅途比较愉快的,主要是刚接触,比较有兴趣,还有就是sqlite的数据库语法和MSSQL很像,比较快上手。  Via cnblogs.com/aehoo/   2012-02-27  WJF Dev

        附件的内容有:1,System.Data.SQLite.DLL         使用sqlite必要的文件

                             2,System.Data.SQLite.Linq.dll    使用sqlite必要的文件

                             3,SqliteHelper.cs    被我称为数据库操作类

                             4,SQLiteTest      一个测试demo

                             点击下载附件:下载

  • 相关阅读:
    [充电]多线程无锁编程--原子计数操作:__sync_fetch_and_add等12个操作
    [转]架构、框架、模式、模块、组件、插件、控件、中间件的含义
    [网络]网络爬虫
    PHP时间戳和日期转换
    两个input之间有空隙,处理方法
    去除输入框原始效果【原创】
    php做图片上传功能
    PHP获取随机数的函数rand()和mt_rand()
    PHP简单的图片上传
    基于layui的表格异步删除,ajax的简单运用
  • 原文地址:https://www.cnblogs.com/aehoo/p/TreeViewAndSqlite.html
Copyright © 2020-2023  润新知