首页 / 教程列表 / C#+ADO.NET数据库入门教程 / C#+ADO.NET读取MSSQL Server数据库中的数据

C#+ADO.NET读取MSSQL Server数据库中的数据

675 更新于: 2022-02-28 读完约需 5 分钟

概述

上一节《C#+ADO.NET连接MSSQL Server数据库》,我们使用ADO.NET实现了基础的C#应用程序与SQL Server数据库连接功能。但这只是C#应用程序与SQL Server数据交互的开端。

连接数据库的目的当然是要对数据库、数据表的结构或者数据进行操作,如:创建数据库,创建/修改表结构,向数据表中写入数据,更新数据,查询数据甚至删除数据等等。

本节,我们将学习在C#应用程序中使用ADO.NET从SQL Server数据库中查询数据并在.NET 5的控制台应用程序中显示。

准备工作

在本节教程开始之前,先准备一张数据表并在其中填充测试用的数据。你可以在 Datum 这个数据生成网站生成模拟数据。

以下是笔者准备的SQL Server数据库的表结构脚本如下:

CREATE TABLE Customer (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    FamilyName NVARCHAR(50),
    GivenName NVARCHAR(50),
    Email NVARCHAR(50),
    Gender NVARCHAR(10),
    IpAddress NVARCHAR(20),
    CreatedAt DATETIME
);

请点击这里获取完整示例脚本 —> C#+ADO.NET读取MSSQL Server数据库中的数据(示例SQL脚本)

通过DataReader检索数据

要使用DataReader检索数据,首先需要创建Command对象的实例,然后通过调用Command.ExecuteReader()方法以创建DataReader并从数据源获取数据。当检索大量数据时,因为数据不会缓存在内存中,DataReader是一个很好的选择。

以下是使用Command创建DataReader并从数据源检索数据的示例,代码如下:

using System;
using System.Data.SqlClient;

namespace ConsoleApp1
{
    class Program
    {
        // 定义一个私有字段,存储数据库连接字符串信息(这里连接的是mssqllocaldb数据库,登录方式为Windows身份验证)
        private const string _connectionString = "Server=(localdb)\\mssqllocaldb;Integrated Security=true;Database=Demo";
        static void Main(string[] args)
        {
            // 1.实例化一个SQL Server的连接对象(这里使用using语句块,以自动释放连接资源)
            using SqlConnection connection = new SqlConnection(_connectionString);
            // 2.实例化一个SqlCommand对象(command),构造函数参数分别为SQL查询语句和SqlConnection数据库连接对象
            var command = new SqlCommand("SELECT TOP 100 Id,FamilyName,GivenName,Email,Gender,IpAddress,CreatedAt FROM Customer", connection);
            // 3.打开数据库连接
            connection.Open();
            // 4.调用command.ExecuteReader()创建SqlDataReader对象并检索数据
            using SqlDataReader reader = command.ExecuteReader();
            // 5.检查reader对象中是否有数据源返回的数据行
            if (reader.HasRows)
            {
                // 6.使用while依次读取reader对象中的每一行数据,直到读取完最后一行
                while (reader.Read())
                {
                    // 7.取数据行中的列,并将其打印到控制台
                    Console.Write($"Id:{reader["Id"]}");
                    Console.Write($"\t姓名:{reader["FamilyName"]}{reader["GivenName"]}");
                    Console.Write($"\t邮箱:{reader["Email"],-30}");
                    Console.Write($"\t性别:{reader["Gender"]}");
                    Console.Write($"\tIP地址:{reader["IpAddress"],-15}");
                    Console.Write($"\t创建时间:{reader["CreatedAt"],-15}");
                    // 换行
                    Console.WriteLine();
                }
            }
            Console.ReadKey();
        }

    }
}

示例代码中的:\t:制表符, {reader[“Email”],-30}:左对齐,如果少于30个字符,则用空格补齐

运行结果如下图:

读取DataReader行中的列元素有两种方式,一种是上面示例的reader["列名"],另一种是通过列的索引方式,如:GetDateTime, GetDouble, GetGuid, GetInt32等等方法,如图:

其中:reader["列名"]方式只需要指定正确的列名即可,得到的数据类型是object,而第二种调用Get方法需要知道数据源的原始数据类型,并且还要指定列的索引位置,而得到的是显式的数据类型,如图示:

注: DataReader没有直接返回数据行数的属性或方法。也就是说,你不能通过DataReader的实例直接得到当前实例中的总数据行数,想要得到当前DataReader实例的数据行数,需要自己实现(一种方案为:在循环中累加计数)。

特别注意: 在使用完后,请调用reader.Close()方法关闭DataReader(本示例中使用了using语句,会自动释放)。

通过DataSet检索数据

ADO.NET除了可以使用DataReader检索数据外,还有DataSet可以返回数据,且结果是一个数据集。

正如前面小节《ADO.NET五大核心对象》中介绍的,DataSet(数据集)是ADO.NET的核心。DataSet本质上是DataTable对象的集合。每个对象依次包含一个DataColumnDataRow对象的集合。数据集还包含一个关系集合,可用于定义数据表对象之间的关系。

DataSet是驻留于内存中的数据集,可以看做是内存中的数据库,内部用XML来描述数据。而数据集(DataSet)与数据源之间检索和保存数据则是通过DataAdapter这个数据适配器来完成的。

以下演示使用ADO.NET从SQL Server数据库中检索指定数据表并输出到.NET 5控制台应用程序,示例代码如下:

using System;
using System.Data;
using System.Data.SqlClient;

namespace ConsoleApp1
{
    class Program
    {
        // 定义一个私有字段,存储数据库连接字符串信息(这里连接的是mssqllocaldb数据库,登录方式为Windows身份验证)
        private const string _connectionString = "Server=(localdb)\\mssqllocaldb;Integrated Security=true;Database=Demo";
        static void Main(string[] args)
        {
            // 1.实例化一个SQL Server的连接对象(这里使用using语句块,以自动释放连接资源)
            using SqlConnection connection = new SqlConnection(_connectionString);
            // 2.实例化一个SqlDataAdapter数据适配器对象(adapter),构造函数参数分别为SQL查询语句和SqlConnection数据库连接对象
            SqlDataAdapter adapter = new SqlDataAdapter("SELECT TOP 100 Id,FamilyName,GivenName,Email,Gender,IpAddress,CreatedAt FROM Customer", connection);
            // 3.创建一个DataSet实例,DataSet位于命名空间System.Data,请注意引入
            DataSet ds = new DataSet();

            // 通过DataAdapter,有以下三种方式获取到数据表DataTable

            // 方式一
            // 4.调用Fill方法将数据填充到数据集对象ds中,如果指定数据库连接未打开,Fill方法会隐式打开数据库连接
            adapter.Fill(ds);
            // 5.从数据集对象ds中取出第一个(下标为0)数据表,设置其变量名为table
            DataTable table = ds.Tables[0];

            // 方式二
            // Fill方法还有重载方法,第二个参数表示目标表的表名,如下:
            // adapter.Fill(ds,"customer");
            // 通过目标表的表名获取DataTable数据表 
            // DataTable customer = ds.Tables["customer"];

            // 方式三
            // Fill方法的另一个重载方法,参数为一个DataTable实例对象,如下:
            // adapter.Fill(table);

            // 6.得到数据表table中的所有数据行集合,设置其变量名为rows
            DataRowCollection rows = table.Rows;
            // 7.打印出当前数据行集合中所有的数据总行数
            Console.WriteLine($"总行数:{rows.Count}");
            // 8.循环遍历数据行集合的每一行
            for (int i = 0; i < rows.Count; i++)
            {
                // 9.循环中的当前行
                var row = rows[i];
                // 10.通过列名读取当前行指定列的值,并打印到控制台
                Console.Write($"Id:{row["Id"]}");
                Console.Write($"\t姓名:{row["FamilyName"]}{row["GivenName"]}");
                Console.Write($"\t邮箱:{row["Email"],-30}");
                Console.Write($"\t性别:{row["Gender"]}");
                Console.Write($"\tIP地址:{row["IpAddress"],-15}");
                Console.Write($"\t创建时间:{row["CreatedAt"],-15}");
                Console.WriteLine();
            }

            // 通常需调用connection.Close();方法关闭数据库连接
            // 但上面使用了using关键字,所以此处无需手动关闭(connection作用域结束时,会自动释放connection资源)

            Console.ReadKey();
        }

    }
}

运行结果如下图:

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

发表评论

登录用户才能发表评论, 请 登 录 或者 注册