zl程序教程

您现在的位置是:首页 >  后端

当前栏目

C#数据库教程7-ADO.NET三层架构和数据库DBNull问题

c#Net数据库架构教程 三层 ADO 问题
2023-09-11 14:16:29 时间

目录

一、数据库中创建表

1、创建数据表T_Person

2、向数据表T_Person中插入数据

3、查看插入的数据

二、 创建C# Winform工程

1、添加引用

 2、编辑数据库连接配置文件

 3、添加封装的数据库类

 三、添加具体业务功能代码

1、创建三层架构

2、查询数据表中的数据总条数

3、删除数据表中指定ID的数据

4、向数据库中插入数据 

5、向数据库中插入Null的问题

6、读取指定ID号的数据

7、读取数据库值为DBNull的处理方法

工程下载


一、数据库中创建表

1、创建数据表T_Person

列AiHao这种不确定的类型,可以为nvarchar(MAX)。

2、向数据表T_Person中插入数据

使用查询语句,向数据库中插入4条数据

insert into T_Person(Name,Age,AiHao,Height,BirthDay) values ('Pan',20,'BasketBall',130.00,'1995-09-16')
insert into T_Person(Name,Age,AiHao,Height,BirthDay) values ('Li',30,'FoottBall',110.09,'1985-11-12')
insert into T_Person(Name,Age,AiHao,Height,BirthDay) values ('Wang',40,'Swim',150.59,'1975-01-26')
insert into T_Person(Name,Age,Height,BirthDay) values ('Xu',32,119,'1989-01-02')

3、查看插入的数据

在数据表T_Person中右击编辑前200项,查看插入的四条数据

二、 创建C# Winform工程

1、添加引用

 2、编辑数据库连接配置文件

App.config配置文件

 3、添加封装的数据库类

添加前面章节中讲解所封装的SqlHelper类

 三、添加具体业务功能代码

所谓三层架构一般描述为:表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL)。本测试比较简单,将业务逻辑就放在UI中处理了。

1、创建三层架构

(1)创建UI窗口界面

UI层即界面层,这一层不出现任何数据库访问代码

(2)创建数据访问层DAL处理类

具体功能代码实现,后面具体展开

(3)创建Model

(Model不属于三层架构)

    class PersonModel
    {
        //若在数据库中为可空类型,则C#中定义的数据类型后加?,string自带可空功能可不用添加,int则为int?  

        public long ID { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }

        public string AiHao { get; set; }

        public decimal? Height { get; set; }

        public DateTime? BirthDay  { get; set; }

    }

2、查询数据表中的数据总条数

(1)添加业务处理程序

        /// <summary>
        /// 获取数据总条数
        /// </summary>
        /// <returns></returns>
        public static int GetCount()
        {
            return (int)SqlHelper.ExecuteScalar("select count(*) from T_Person");
        }

(2)添加UI控件

 (3)添加UI程序

        private void btnDataCountGet_Click(object sender, EventArgs e)
        {
            int count = PersonDAL.GetCount();
            txtDataCount.Text = count.ToString();
        }

(4)运行

3、删除数据表中指定ID的数据

(1)添加业务处理程序

        /// <summary>
        /// 删除制定ID行数据
        /// </summary>
        /// <param name="ID"></param>
        public static void DeleteByID(long ID)
        {
            SqlHelper.ExecuteNonQuery("delete from T_Person where ID=@ID",
                        new SqlParameter("@ID", ID));
        }

(2)添加UI控件

(3)添加UI程序

        private void btnDeleteData_Click(object sender, EventArgs e)
        {
            long row = int.Parse(txtDeleteRow.Text);
            PersonDAL.DeleteByID(row);
            MessageBox.Show("删除成功", "提示");
        }

(4)运行

先删除指定的第四行,再查询发现数据总数居变成了3条,说明删除成功

 查询数据库中,第四条数据已经删除

4、向数据库中插入数据 

(1)添加业务处理程序

        /// <summary>
        /// 插入数据。
        /// </summary>
        public static void Insert(PersonModel person)
        {
            SqlHelper.ExecuteNonQuery("insert into T_Person(Name,Age,AiHao,Height,BirthDay) values (@_Name,@_Age,@_AiHao,@_Height,@_BirthDay)",
                                    new SqlParameter("@_Name", person.Name),
                                    new SqlParameter("@_Age", person.Age),
                                    new SqlParameter("@_AiHao", person.AiHao),
                                    new SqlParameter("@_Height", person.Height),
                                    new SqlParameter("@_BirthDay", person.BirthDay)
                                    );
        }

(2)添加UI控件

(3)添加UI程序

        private void btnInsert_Click(object sender, EventArgs e)
        {
            PersonModel person = new PersonModel();
            person.Name = txtName.Text;
            person.Age = Convert.ToInt32(txtAge.Text);
            person.AiHao = txtAiHao.Text;
            person.Height = Convert.ToDecimal(txtHeight.Text);
            person.BirthDay = Convert.ToDateTime(txtBirthday.Text);

            PersonDAL.Insert(person);
            MessageBox.Show("插入成功", "提示");
        }

(4)运行

 数据库中查看

5、向数据库中插入Null的问题

(1)插入null

如数据库中的 ‘AiHao’列为可空项,将UI中的代码注释,设置断点运行

 则在写数据时插入null代码异常,SqlHelper类中封装的SQL执行语句显示为缺少未输入参数

 (2)解决方法

修改DAL中的代码,在插入数据库之前先判断该项若为null值、则先转换成数据库中的DBNull值类型。

        /// <summary>
        /// 插入数据。
        /// </summary>
        public static void Insert(PersonModel person)
        {
            object _aiHao;
            if (person.AiHao==null)
            {
                _aiHao = DBNull.Value;
            }
            else
            {
                _aiHao = person.AiHao;
            }

            SqlHelper.ExecuteNonQuery("insert into T_Person(Name,Age,AiHao,Height,BirthDay) values (@_Name,@_Age,@_AiHao,@_Height,@_BirthDay)",
                                    new SqlParameter("@_Name", person.Name),
                                    new SqlParameter("@_Age", person.Age),
                                    new SqlParameter("@_AiHao", _aiHao),
                                    new SqlParameter("@_Height", person.Height),
                                    new SqlParameter("@_BirthDay", person.BirthDay)
                                    );
        }

再次运行则发现成功写入

 (3)封装该方法应用于其它几个可空的列

封装方法

        /// <summary>
        /// 抽象的方法:判断往数据库写的数据是否为null
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static object ToDBValue(object value)
        {
            if (value == null)
            {
                return DBNull.Value;
            }
            else
            {
                return value;
            }
        }

 修改DAL的Insert方法

        /// <summary>
        /// 插入数据。
        /// </summary>
        public static void Insert(PersonModel person)
        {
            SqlHelper.ExecuteNonQuery("insert into T_Person(Name,Age,AiHao,Height,BirthDay) values (@_Name,@_Age,@_AiHao,@_Height,@_BirthDay)",
                                    new SqlParameter("@_Name", person.Name),
                                    new SqlParameter("@_Age", person.Age),
                                    new SqlParameter("@_AiHao", ToDBValue(person.AiHao)),
                                    new SqlParameter("@_Height", ToDBValue(person.Height)),
                                    new SqlParameter("@_BirthDay", ToDBValue(person.BirthDay))
                                    );
        }

成功插入数据

6、读取指定ID号的数据

DAL中不要返回DataTable、DataRow等ADO.Net的类

(1)添加业务处理程序

读取的数据库表中的数据可能包含DBNull

        /// <summary>
        /// 读取数据表中指定ID的数据
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public static PersonModel GetByID(long id) 
        {
            DataTable table = SqlHelper.ExecuteDataTable("select * from T_Person where ID=@ID",
                new SqlParameter("@ID", id));
            if (table.Rows.Count <= 0)
            {
                return null;    //不存在
            }
            else if (table.Rows.Count > 1)
            {
                //主键重复
                throw new Exception("ID存在重复");     
            }
            else
            {
                //DAL中不要返回DataTable、DataRow等ADO.Net的类
                DataRow row = table.Rows[0];
                PersonModel person = new PersonModel();
                person.ID = (long)row["ID"];
                person.Name = (string)row["Name"];
                person.Age = (int)row["Age"];
                if (row["AiHao"]==DBNull.Value)
                {
                    person.AiHao = null;
                }
                else
                {
                    person.AiHao = (string)row["AiHao"];
                }
                person.Height = (decimal?)row["Height"];            //可空类型
                person.BirthDay = (DateTime?)row["BirthDay"];       //可空类型

                return person;
            }

(2)运行测试

UI按钮事件程序中设置断点测试,读取I数据表中,ID为8的数据

7、读取数据库值为DBNull的处理方法

(1)封装判断读取值是否为DBNull方法

        /// <summary>
        /// 抽象的方法,判断从数据库中读的数据是否为null。如果value这个数据库中的值为DBNull,则返回null
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static object FromDBValue(object value)
        {
            if(value==DBNull.Value)
            {
                return null;
            }
            else
            {
                return value;
            }
        }

(2)修改DAL中的GetByID程序

        /// <summary>
        /// 读取数据表中指定ID的数据
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public static PersonModel GetByID(long id) 
        {
            DataTable table = SqlHelper.ExecuteDataTable("select * from T_Person where ID=@ID",
                new SqlParameter("@ID", id));
            if (table.Rows.Count <= 0)
            {
                return null;    //不存在
            }
            else if (table.Rows.Count > 1)
            {
                //主键重复
                throw new Exception("ID存在重复");     
            }
            else
            {
                //DAL中不要返回DataTable、DataRow等ADO.Net的类
                DataRow row = table.Rows[0];
                PersonModel person = new PersonModel();
                person.ID = (long)row["ID"];
                person.Name = (string)row["Name"];
                person.Age = (int)row["Age"];
                person.AiHao = (string)FromDBValue(row["AiHao"]);               //string本身就是可空类型
                person.Height = (decimal?)FromDBValue(row["Height"]);            //可空类型
                person.BirthDay = (DateTime?)FromDBValue(row["BirthDay"]);       //可空类型

                return person;
            }

(3)添加UI控件

(4) 添加UI层按钮程序

         private void btnRead_Click(object sender, EventArgs e)
        {
            long id = int.Parse(txtReadID.Text);
            PersonModel person = PersonDAL.GetByID(id);

            //txtReadID.Text = person.ID.ToString();
            txtReadName.Text = person.Name;
            txtReadAge.Text = person.Age.ToString();
            txtReadHeight.Text = person.Height.ToString();
            txtReadBirthDay.Text = person.BirthDay.ToString();
            txtReadAiHao.Text = person.AiHao;

            MessageBox.Show("读取成功", "提示");
        }

(5)运行程序,读取

读取第3行 

读取第8行 

若有任何问题,欢迎私聊我。

工程下载

https://download.csdn.net/download/panjinliang066333/85439817