• Winform分页控件更新之集成Sqlite数据库分页


    在Winform开发中,一直离不开分页处理,好的分页控件封装,能为开发节省很多时间和繁琐工作,对分页控件一直的改进和完善,也是我的兴趣之一。分页控件一直都有一些小的更新,不过基本上已能满足大多数的使用场景了。有一天,一个朋友告诉我:我们项目用的是Sqlite数据库做项目,这个分页控件能支持实现分页吗?由于分页控件虽然不直接访问数据,不过需要根据不同的数据库来构造不同的分页语句,因为之前听说过但没怎么研究过Sqlite数据库,当然也没有提供支持了。

    既然朋友需要,那就得研究下,并提供相关的支持,经过一番小修改,即可完成内容的Sqlite分页支持了。在给出相关的分页实现例子之前,我们介绍一下,为什么项目使用Sqlite而不是使用Access数据库,他们之间有那些特点。 

    1、Access特点

    我们做小项目的时候特别是小的MIS系统一般也都要用数据库来保存数据,大部分的小系统都是用Access数据库,Access使用上确实非常方便,也方便对数据进行管理维护等优点,复制过去即可使用。但其实Access数据库本身也存在很多的问题:性能不行;数据不安全,用户可以直接用Access打开数据库文件进行数据修改,即使加密后都可以直接破解;Access的数据量一大,文件本身的体积就异常庞大;Access数据库文件很容易损坏等。 

    2、 SQLite特点

    SQLite是一个小型的C程序库,实现了独立的,可嵌入的,零配置的SQL数据库引擎,SQLite用的非常广泛,Web应用也都在用它,PHP5内置了SQLite的扩展,所以SQLite是桌面轻量级数据库的首选。
    • 事务操作是原子,一致,孤立,并且持久的(ACID),即使在系统崩溃和电源故障之后。

    • 零配置——不需要安装和管理。

    • 实现了绝大多数SQL92标准。

    • 整个数据库存储在一个单一的文件中。

    • 数据库文件可以在不同字节序的机器之间自由地共享。

    • 支持最大可达2T的数据库。 (241 字节)

    • 字符串和BLOB类型的大小最大可达 2G 字节(231字节)。

    • 小的代码: 完整配置的少于250KB,忽略一些可选特性的少于150KB。

    • 在大多数常见操作上比流行的客户/服务器数据库引擎更快。

    • 简单,易于使用的API。

    • 内建TCL绑定。 另外提供可用于许多其他语言的绑定。

    • 具有良好注释的源代码,95%经过测试。

    • 独立:没有外部依赖。

    • 源代码位于公共域。 可用于任何用途。

     朋友介绍操作SQLite使用工具SQLiteSpy,实际上这个工具不支持数据库(如Access数据库)的导入,偶然发现还有SQLite Developer这样一个工具,管理上非常方便,操作图如下所示,使用发现功能比较丰富,支持对表字段定义的直接修改,编辑数据、Sql查询、创建、压缩、备份数据库等,对中文支持也不错。

     

     

     

    言归正题,介绍完毕一些SQLite的使用后,继续介绍分页控件如何实现SQLite的分页处理吧。 

    普通版本的分页控件呈现效果如下所示。

      

    DevExpress样式版本的分页控件效果如下所示(均支持SQLite分页)

      

    基于SqlLite数据库的分页控件使用例子代码如下:

            string connectionString = "";

            public FrmCustomer()
            {
                InitializeComponent();

                connectionString = string.Format(@"Data Source={0}\OrderWater.db;Version=3;", Application.StartupPath);
            }

            private void FrmCustomer_Load(object sender, EventArgs e)
            {
                this.winGridViewPager1.OnPageChanged += new EventHandler(winGridViewPager1_OnPageChanged);
                this.winGridViewPager1.OnStartExport += new EventHandler(winGridViewPager1_OnStartExport);
                this.winGridViewPager1.OnEditSelected += new EventHandler(winGridViewPager1_OnEditSelected);
                this.winGridViewPager1.OnDeleteSelected += new EventHandler(winGridViewPager1_OnDeleteSelected);
                this.winGridViewPager1.OnRefresh += new EventHandler(winGridViewPager1_OnRefresh);
                this.winGridViewPager1.OnAddNew += new EventHandler(winGridViewPager1_OnAddNew);
                this.winGridViewPager1.AppendedMenu = this.contextMenuStrip1;
                this.winGridViewPager1.ShowLineNumber = true;//显示行号
                this.winGridViewPager1.PagerInfo.PageSize = 20;//页面大小
                this.winGridViewPager1.EventRowBackColor = Color.LightCyan;//间隔颜色

                BindData();
            }

            private void winGridViewPager1_OnRefresh(object sender, EventArgs e)
            {
                BindData();
            }

            private void winGridViewPager1_OnDeleteSelected(object sender, EventArgs e)
            {
                if (MessageUtil.ShowYesNoAndTips("您确定删除选定的记录么?") == DialogResult.No)
                {
                    return;
                }

                DataGridView grid = this.winGridViewPager1.dataGridView1;
                if (grid != null)
                {
                    foreach (DataGridViewRow row in grid.SelectedRows)
                    {
                        //BLLFactory<Customer>.Instance.Delete(row.Cells[0].Value.ToString());
                    }
                    BindData();
                }
            }

            private void winGridViewPager1_OnEditSelected(object sender, EventArgs e)
            {
                DataGridView grid = this.winGridViewPager1.dataGridView1;
                if (grid != null)
                {
                    foreach (DataGridViewRow row in grid.SelectedRows)
                    {
                        FrmEditCustomer dlg = new FrmEditCustomer();
                        dlg.ID = row.Cells[0].Value.ToString();
                        if (DialogResult.OK == dlg.ShowDialog())
                        {
                            BindData();
                        }

                        break;
                    }
                }
            }

            private void winGridViewPager1_OnStartExport(object sender, EventArgs e)
            {
                string where = GetSearchSql();
                PagerInfo info = new PagerInfo();
                info.CurrenetPageIndex = 1;
                info.PageSize = int.MaxValue;
                this.winGridViewPager1.AllToExport = FindToDataTable(where, info);
            }

            private void winGridViewPager1_OnPageChanged(object sender, EventArgs e)
            {
                BindData();
            }

            #region 查询辅助函数

            /// <summary>    
            
    /// 执行SQL查询语句,返回查询结果的所有记录的第一个字段,用逗号分隔。    
            
    /// </summary>    
            
    /// <param name="sql">SQL语句</param>    
            
    /// <returns>    
            
    /// 返回查询结果的所有记录的第一个字段,用逗号分隔。    
            
    /// </returns>    
            public string SqlValueList(string sql)
            {
                SQLiteConnection connection = new SQLiteConnection(connectionString);
                SQLiteCommand cmd = new SQLiteCommand(sql, connection);

                connection.Open();
                StringBuilder result = new StringBuilder();
                using (SQLiteDataReader dr = cmd.ExecuteReader())
                {
                    while (dr.Read())
                    {
                        result.AppendFormat("{0},", dr[0].ToString());
                    }
                }

                string strResult = result.ToString().Trim(',');
                return strResult;
            }

            /// <summary>    
            
    /// 执行SQL查询语句,返回所有记录的DataTable集合。    
            
    /// </summary>    
            
    /// <param name="sql">SQL查询语句</param>    
            
    /// <returns></returns>    
            public DataTable SqlTable(string sql)
            {
                DataSet ds = new DataSet();
                SQLiteDataAdapter adpater = new SQLiteDataAdapter(sql, connectionString);
                adpater.Fill(ds);
                
                return ds.Tables[0];
            }

            /// <summary>
            
    /// 标准的记录查询函数
            
    /// </summary>
            
    /// <param name="where"></param>
            
    /// <param name="pagerInfo"></param>
            
    /// <returns></returns>
            private DataTable FindToDataTable(string where, PagerInfo pagerInfo)
            {
                WHC.Pager.WinControl.PagerHelper helper = new WHC.Pager.WinControl.PagerHelper("All_Customer""*""LastUpdated", pagerInfo.PageSize, pagerInfo.CurrenetPageIndex, truewhere);
                string countSql = helper.GetPagingSql(WHC.Pager.WinControl.DatabaseType.SQLite, true);
                string dataSql = helper.GetPagingSql(WHC.Pager.WinControl.DatabaseType.SQLite, false);

                string value = SqlValueList(countSql);
                pagerInfo.RecordCount = Convert.ToInt32(value);//为了显示具体的信息,需要设置总记录数
                DataTable dt = SqlTable(dataSql);
                return dt;
            }

            /// <summary>
            
    /// 根据查询条件构造查询语句
            
    /// </summary>
            
    /// <returns></returns>
            private string GetSearchSql()
            {
                SearchCondition condition = new SearchCondition();
                condition.AddCondition("Number"this.txtNumber.Text, SqlOperator.Like)
                    .AddCondition("Name"this.txtName.Text, SqlOperator.Like)
                    .AddCondition("Type"this.cmbType.Text, SqlOperator.Like)
                    .AddCondition("Area"this.cmbArea.Text, SqlOperator.Like)
                    .AddCondition("Address"this.txtAddress.Text, SqlOperator.Like)
                    .AddCondition("Company"this.txtCompany.Text, SqlOperator.Like)
                    .AddCondition("Note"this.txtNote.Text, SqlOperator.Like)
                    .AddCondition("Telephone1"this.txtTelephone.Text, SqlOperator.Like, true"Telephone")
                    .AddCondition("Telephone2"this.txtTelephone.Text, SqlOperator.Like, true"Telephone")
                    .AddCondition("Telephone3"this.txtTelephone.Text, SqlOperator.Like, true"Telephone")
                    .AddCondition("Telephone4"this.txtTelephone.Text, SqlOperator.Like, true"Telephone")
                    .AddCondition("Telephone5"this.txtTelephone.Text, SqlOperator.Like, true"Telephone");

                if (chkUseDate.Checked)
                {
                    condition.AddCondition("CreateDate", dateTimePicker1.Value.ToString("yyyy-MM-dd"), SqlOperator.MoreThanOrEqual, true)
                        .AddCondition("CreateDate", dateTimePicker2.Value.AddDays(1).ToString("yyyy-MM-dd"), SqlOperator.LessThanOrEqual, true);

                }
                string where = condition.BuildConditionSql().Replace("Where""");
                return where;
            } 
            #endregion

            private void BindData()
            {
                #region 添加别名解析
                //DisplayColumns与显示的字段名或者实体属性一致,大小写不敏感,顺序代表显示顺序,用逗号或者|分开
                this.winGridViewPager1.DisplayColumns = "Number,NAME,type,Area,Company,Address,Telephone1,Telephone2,Telephone3,Telephone4,Telephone5,CreateDate,Note,LastUpdated";
                this.winGridViewPager1.AddColumnAlias("ID""编号");
                this.winGridViewPager1.AddColumnAlias("Number""客户编号");
                this.winGridViewPager1.AddColumnAlias("Name""客户名称");
                this.winGridViewPager1.AddColumnAlias("Type""客户类型");
                this.winGridViewPager1.AddColumnAlias("Area""客户地区");
                this.winGridViewPager1.AddColumnAlias("Company""客户单位");
                this.winGridViewPager1.AddColumnAlias("Address""客户地址");
                this.winGridViewPager1.AddColumnAlias("Telephone1""电话1");
                this.winGridViewPager1.AddColumnAlias("Telephone2""电话2");
                this.winGridViewPager1.AddColumnAlias("Telephone3""电话3");
                this.winGridViewPager1.AddColumnAlias("Telephone4""电话4");
                this.winGridViewPager1.AddColumnAlias("Telephone5""电话5");
                this.winGridViewPager1.AddColumnAlias("CreateDate""开户日期");
                this.winGridViewPager1.AddColumnAlias("Shop_ID""分店ID");
                this.winGridViewPager1.AddColumnAlias("Note""备注");
                this.winGridViewPager1.AddColumnAlias("LastUpdated""更新日期");

                #endregion

                string where = GetSearchSql();
                this.winGridViewPager1.DataSource = FindToDataTable(wherethis.winGridViewPager1.PagerInfo);
            }

            private void btnSearch_Click(object sender, EventArgs e)
            {
                BindData();
            } 

     

    以上例子关键的地方有3个

    1、 数据库字符串

    connectionString = string.Format(@"Data Source={0}\OrderWater.db;Version=3;", Application.StartupPath); 

    2.、查询数据操作

    数据查询通过调用 System.Data.SQLite.DLL 的程序集实现数据访问操作,如下所示。

            public DataTable SqlTable(string sql)
            {
                DataSet ds = new DataSet();
                SQLiteDataAdapter adpater = new SQLiteDataAdapter(sql, connectionString);
                adpater.Fill(ds);
                
                return ds.Tables[0];
            } 

    3、 SQLite分页语句调用生成 

    调用内置的类实现分页语句的生成,代码如下所示。

                WHC.Pager.WinControl.PagerHelper helper = new WHC.Pager.WinControl.PagerHelper("All_Customer""*""LastUpdated", pagerInfo.PageSize, pagerInfo.CurrenetPageIndex, truewhere);
                string countSql = helper.GetPagingSql(WHC.Pager.WinControl.DatabaseType.SQLite, true);

                string dataSql = helper.GetPagingSql(WHC.Pager.WinControl.DatabaseType.SQLite, false); 

    完整可运行例子如下下载即可:

    https://files.cnblogs.com/wuhuacong/TestPager_SqlLite.rar 

    主要研究技术:代码生成工具、会员管理系统、客户关系管理软件、病人资料管理软件、Visio二次开发、酒店管理系统、仓库管理系统等共享软件开发
    专注于Winform开发框架/混合式开发框架Web开发框架Bootstrap开发框架微信门户开发框架的研究及应用
      转载请注明出处:
    撰写人:伍华聪  http://www.iqidi.com 
        
  • 相关阅读:
    Redis系列5:深入分析Cluster 集群模式 Hello
    架构与思维:互联网高性能Web架构 Hello
    Java核心知识体系3:异常机制详解 Hello
    Redis系列4:高可用之Sentinel(哨兵模式) Hello
    Java核心知识体系4:AOP原理和切面应用 Hello
    Java核心知识体系2:注解机制详解 Hello
    MQ系列3:RocketMQ 架构分析 Hello
    Redis系列3:高可用之主从架构 Hello
    MQ系列2:消息中间件的技术选型 Hello
    MQ系列4:NameServer 原理解析 Hello
  • 原文地址:https://www.cnblogs.com/wuhuacong/p/2262068.html
Copyright © 2020-2023  润新知