.NET 操作数据库之ADO.NET和ORM

一、前言

任何一个应用程序都离不开数据的存储,数据可以在内存中存储,但只能在程序运行时存取,无法持久保存。

数据还可以在磁盘中以文件的形式存储,但文件的管理和查找又十分烦琐无法胜任大数量的存储。

将数据存储到数据库中是在应用程序中持久存储数据的常用方式。

在 C# 语言中提供了 ADO.NET 组件来实现连接数据库以及操作数据库中数据的功能。

二、使用ADO.NET操作数据库

在 C#语言中 ADO.NET 是在 ADO 的基础上发展起来的,ADO (Active Data Object) 是一个 COM 组件类库,用于访问数据库,而 ADO.NET 是在 .NET 平台上访问数据库的组件。

ADO.NET 是以 ODBC (Open Database Connectivity) 技术的方式来访问数据库的一种技术。下面我们通过winform窗体应用来使用ADO.NET。

1.新建winform程序,放置一个按钮,用来测试数据库连接。

2.在forms1.cs里引用using System.Data.SqlClient;并写一个连接sql的方法

 static SqlConnection Conn()
        {
            //编写数据库连接串
            string connStr = "Data source=.;Initial Catalog=test;User ID=sa;Password=sa123";
            //创建SqlConnection的实例
            SqlConnection conn = null;
            try
            {
                conn = new SqlConnection(connStr);
                //打开数据库连接
                conn.Open();
                MessageBox.Show("数据库连接成功!");
            }
            catch (Exception ex)
            {
                conn.Close();
                MessageBox.Show("数据库连接失败!" + ex.Message);
            }
            finally
            {
                if (conn != null)
                {
                    //关闭数据库连接
                    conn.Close();
                }
            }
            return conn;
        }

3.新建全局变量 conn,并绑定按钮点击事件,这样就不用每次操作都要连接一下数据库:

        public SqlConnection conn;
        private void test_conn_Click(object sender, EventArgs e)
        {
            conn = Conn();

        }

4.运行程序,点击按钮,如果连接成功会提示连接成功,如果失败提示失败原因。

5.数据库连接成功,下面开始插入数据。新建表t_product,定义三个字段,id,name,stock,id设为主键并自增。

6.放置一个添加按钮,并绑定点击事件。

private void add_Click(object sender, EventArgs e)
        {
            if (conn!=null)
            {
                try
                {
                    conn.Open();
                    string sql = "insert into t_product(Name,Stock) values('{0}',{1})";
                    //填充SQL语句
                    sql = string.Format(sql, "商品1", 53);
                    //创建SqlCommand对象
                    SqlCommand cmd = new SqlCommand(sql, conn);
                    //执行SQL语句
                    int returnvalue = cmd.ExecuteNonQuery();
                    //判断SQL语句是否执行成功
                    if (returnvalue != -1)
                    {
                        MessageBox.Show("插入数据成功!");
                    }
                }
                catch (Exception ex)
                {

                    MessageBox.Show("插入数据失败!" + ex.Message);
                }
                finally
                {
                    if (conn != null)
                    {
                        //关闭数据库连接
                        conn.Close();
                    }
                }

            }
            else
            {
                MessageBox.Show("请检查数据库连接!");
            }

        }

7.多次点击添加按钮,提示添加成功,数据库查看数据。

8.插入数据没问题,下面开始查询数据,页面放置查询按钮,用来查询数据,一个listview控件,用来显示信息。

 9.绑定查询事件,点击查询按钮,listview显示数据库的数据:

private void query_all_Click(object sender, EventArgs e)
        {
            if (conn != null)
            {
                try
                {
                    string sql = "select Name from t_product";
                    //创建 SqlDataAdapter 类的对象
                    SqlDataAdapter sda = new SqlDataAdapter(sql, conn);
                    //创建 DataTable 类的对象
                    DataTable dt = new DataTable();
                    //使用 SqlDataAdapter 对象 sda 将查询结果填充到 DataSet 对象 dt 中
                    sda.Fill(dt);
                    //设置 ListBox 控件的数据源(DataSource)属性
                    pro_list.DataSource = dt;
                    //在 ListBox 控件中显示 name 列的值
                    pro_list.DisplayMember = dt.Columns[0].ToString();
                }
                catch (Exception ex)
                {

                    MessageBox.Show("插入数据失败!" + ex.Message);
                }
                finally
                {
                    if (conn != null)
                    {
                        //关闭数据库连接
                        conn.Close();
                    }
                }

            }
            else
            {
                MessageBox.Show("请检查数据库连接!");
            }
        }

 

三、什么是ORM

ORM(Object Relational Mapping)是对象关系映射。它的实质就是将关系数据(库)中的业务数据用对象的形式表示出来,并通过面向对象(Object-Oriented)的方式将这些对象组织起来,实现系统业务逻辑的过程。在ORM过程中最重要的概念是映射(Mapping),通过这种映射可以使业务对象与数据库分离。从面向对象来说,数据库不应该和业务逻辑绑定到一起,ORM则起到这样的分离作用,使数据库层透明,开发人员真正的面向对象 。

ORM是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。

一般的ORM包括以下四部分:
一个对持久类对象进行CRUD操作的API;
一个语言或API用来规定与类和类属性相关的查询;
一个规定mapping metadata的工具;
一种技术可以让ORM的实现同事务对象一起进行dirty checking, lazy association fetching以及其他的优化操作。

三、使用Entity Framework

1.安装EF

 2.创建实体类User

namespace WindowsFormsApp1
{
    [Table("t_user")]//设置表名
    public class User
    {
        [Key]
        public int Id { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }

    }
}

3.为实体类创建一个数据库上下文类DbContext:

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApp1
{
    class UserDbContext: System.Data.Entity.DbContext
    {
        /// <summary>
        /// 
        /// 数据库上下文类中存在了一个构造函数,一个用来操作的数据库的上下文,被DbSet定义的user。
        ///构造函数的作用是定义一个连接数据库的字符串"Conn"。
        /// </summary>
        public UserDbContext() : base("Conn")
        {

        }

        /// <summary>
        /// 被DbSet定义的user就是我们用来操作数据库的上下文,里面存在了常用的Add,Delete,Save等增删改查方法。
        /// </summary>
        public DbSet<User> user{ get; set; }
    }
}

 

4.配置app.config文件,添加<connectionStrings>属性<add>里面主要存在三个重要配置信息,name为上下文类设置的连接字符串,connectionStrings为连接数据库信息,providerName定义了连接不同数据库的类型,这里为sqlserver

    <connectionStrings>
        <add name="Conn" connectionString="server=.;uid=sa;pwd=sa123;database=." providerName="System.Data.SqlClient" />
    </connectionStrings>

5.页面新建一个按钮,用来操作EF插入数据,并绑定点击事件。

    private void ef_add_Click(object sender, EventArgs e)
        {
            try
            {
                UserDbContext db = new UserDbContext();

                User pd = new User();
                pd.Name = "张三";
                pd.Age = 11;
                db.user.Add(pd);
                db.SaveChanges();
                MessageBox.Show("EF插入数据成功!");
            }
            catch (Exception ex)
            {

                MessageBox.Show("EF插入数据失败!" + ex.Message);
            }
        }

点击按钮提示插入成功。

 6.EF查询有三种方式,所以我们在页面新建三个按钮用来查询数据,分别绑定三个按钮的点击事件。

 

初始数据:

private void ef_query1_Click(object sender, EventArgs e)
        {
            try
            {
                UserDbContext db = new UserDbContext();
                //查询年龄为11的人,并按照ID倒序排序
                var persons = from p in db.user
                              where p.Age == 11
                              orderby p.Id descending
                              select p;
                foreach (var p in persons)
                {
                    user_list.Items.Add(p.Name);
                }
                MessageBox.Show("查询数据成功!");
            }
            catch (Exception ex)
            {

                MessageBox.Show("查询数据失败!" + ex.Message);
            }
        }
Linq查询
方法查询
private void ef_query3_Click(object sender, EventArgs e)
        {
            
            try
            {
                UserDbContext db = new UserDbContext();
                var age =11;
                //查询年龄为11的人,并按照ID倒序排序
                var persons = db.user.SqlQuery($"select * from t_user where Age='{age}' order by id desc");
                foreach (var p in persons)
                {
                    user_list.Items.Add(p.Name);
                }

                //不仅如此,EF还支持非实体类型的查询
                //var persons = db.Database.SqlQuery<string>($"select Name from t_user where Age='{age}' order by id desc");
                //foreach (var p in persons)
                //{
                //    user_list.Items.Add(p);
                //}

                MessageBox.Show("查询数据成功!");
            }
            catch (Exception ex)
            {

                MessageBox.Show("查询数据失败!" + ex.Message);
            }
        }
原生SQL查询

结果:

 

posted @ 2020-04-19 15:41  HuTiger  阅读(2075)  评论(0编辑  收藏  举报