C# ADO.NET
最后修改于 2023 年 7 月 5 日
C# ADO.NET 教程展示了如何使用 ADO.NET 技术在 C# 中进行数据库编程。
ADO.NET
ADO.NET 是一组用于数据库访问的类。它是一个规范,统一了对关系数据库、XML 文件和其他应用程序数据的访问。ADO.NET 类位于 System.Data 命名空间中。
每个数据库必须提供 ADO.NET 规范的实现:MySQL 有 MySQL.Data,PostgreSQL 有 Npgsql,SQLite 有 System.Data.SQLite 或 Microsoft.Data.Sqlite。
$ dotnet add package System.Data.SQLite
要使用 SQLite 数据库,我们需要添加 System.Data.SQLite NuGet 包。
DataSet 对象用于脱机处理大量数据。它是一个断开连接的数据表示,可以保存来自各种不同来源的数据。
ADO.NET SQLite 示例
在第一个示例中,我们使用 SQLite 数据库。
using System.Data.SQLite;
string cs = "Data Source=:memory:";
string stm = "SELECT SQLITE_VERSION()";
using var con = new SQLiteConnection(cs);
con.Open();
using var cmd = new SQLiteCommand(stm, con);
string? version = cmd.ExecuteScalar().ToString();
Console.WriteLine($"SQLite version: {version}");
该示例打印 SQLite 的版本。
string cs = "Data Source=:memory:";
我们使用内存数据库。
string stm = "SELECT SQLITE_VERSION()";
此 SQL 语句确定 SQLite 的版本。
using var con = new SQLiteConnection(cs); con.Open();
SQLiteConnection 创建与特定数据源的连接。参数是 SQL 语句和连接对象。
using var cmd = new SQLiteCommand(stm, con);
SQLiteCommand 对象针对数据源执行 SQL 语句。 using 声明在封闭范围的末尾释放 con 变量。
string? version = cmd.ExecuteScalar().ToString();
ExecuteScalar 返回结果集的第一行第一列(如果存在),如果未返回结果集,则返回 null。
$ dotnet run SQLite version: 3.38.5.1
ADO.NET MySQL 示例
在第二个示例中,我们使用 MySQL。
using MySql.Data.MySqlClient;
string cs = @"server=localhost;userid=user12;password=s$cret;database=testdb";
using var con = new MySqlConnection(cs);
con.Open();
var stm = "SELECT VERSION()";
var cmd = new MySqlCommand(stm, con);
var version = cmd.ExecuteScalar().ToString();
Console.WriteLine($"MySQL version: {version}");
有一些变化。
using MySql.Data.MySqlClient;
我们使用 MySQL 命名空间。
string cs = @"server=localhost;userid=user12;password=s$cret;database=testdb";
连接字符串适用于 MySQL。
using var con = new MySqlConnection(cs);
我们使用 MySqlConnection 而不是 SQLiteConnection。
var stm = "SELECT VERSION()";
SQL 语句是 MySQL 特有的。
var cmd = new MySqlCommand(stm, con);
命令称为 MySqlCommand。
$ dotnet run MySQL version: 8.0.29-0ubuntu0.22.04.2
ADO.NET 创建表
在下面的示例中,我们创建一个数据库表并用数据填充它。
using System.Data.SQLite;
string cs = @"URI=file:test.db";
using var con = new SQLiteConnection(cs);
con.Open();
using var cmd = new SQLiteCommand(con);
cmd.CommandText = "DROP TABLE IF EXISTS cars";
cmd.ExecuteNonQuery();
cmd.CommandText = @"CREATE TABLE cars(id INTEGER PRIMARY KEY,
name TEXT, price INT)";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO cars(name, price) VALUES('Audi',52642)";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO cars(name, price) VALUES('Mercedes',57127)";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO cars(name, price) VALUES('Skoda',9000)";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO cars(name, price) VALUES('Volvo',29000)";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO cars(name, price) VALUES('Bentley',350000)";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO cars(name, price) VALUES('Citroen',21000)";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO cars(name, price) VALUES('Hummer',41400)";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO cars(name, price) VALUES('Volkswagen',21600)";
cmd.ExecuteNonQuery();
Console.WriteLine("table cars created");
在这个例子中,我们创建了一个包含八行数据的 cars 表。
cmd.CommandText = "DROP TABLE IF EXISTS cars"; cmd.ExecuteNonQuery();
首先,如果表已存在,我们先删除它。当我们不想要结果集时,例如对于 DROP、INSERT 或 DELETE 语句,我们使用 ExecuteNonQuery 方法。
cmd.CommandText = @"CREATE TABLE cars(id INTEGER PRIMARY KEY,
name TEXT, price INT)";
cmd.ExecuteNonQuery();
创建了 cars 表。 INTEGER PRIMARY KEY 列在 SQLite 中自动递增。
cmd.CommandText = "INSERT INTO cars(name, price) VALUES('Audi',52642)";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO cars(name, price) VALUES('Mercedes',57127)";
cmd.ExecuteNonQuery();
我们向表中插入两行数据。
$ dotnet run table cars created
我们运行该程序。
$ sqlite3 test.db
我们使用 sqlite3 工具打开 test.db 数据库。
sqlite> SELECT * FROM cars; 1|Audi|52642 2|Mercedes|57127 3|Skoda|9000 4|Volvo|29000 5|Bentley|350000 6|Citroen|21000 7|Hummer|41400 8|Volkswagen|21600
我们验证数据。
ADO.NET 读取数据
在 SQLite 驱动程序中,我们使用 SQLiteDataReader 从数据库中获取数据。 它与 SQLiteCommand 类一起使用,以执行 SELECT 语句并访问返回的行。
using System.Data.SQLite;
string cs = @"URI=file:test.db";
using var con = new SQLiteConnection(cs);
con.Open();
string stm = "SELECT * FROM cars LIMIT 5";
using var cmd = new SQLiteCommand(stm, con);
using SQLiteDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine($"{rdr.GetInt32(0)} {rdr.GetString(1)} {rdr.GetInt32(2)}");
}
我们从 cars 表中获取五行并将其打印到终端。
using SQLiteDataReader rdr = cmd.ExecuteReader();
要创建 SQLiteDataReader 对象,我们调用 SQLiteCommand 对象的 ExecuteReader 方法。
while (rdr.Read())
{
Console.WriteLine($"{rdr.GetInt32(0)} {rdr.GetString(1)} {rdr.GetInt32(2)}");
}
Read 方法将数据读取器前进到下一条记录。 如果有更多行,则返回 true;否则返回 false。 我们可以使用数组索引符号检索值,或者使用特定的方法来访问本机数据类型中的列值。 后者效率更高。
$ dotnet run 1 Audi 52642 2 Mercedes 57127 3 Skoda 9000 4 Volvo 29000 5 Bentley 350000
ADO.NET LINQ 示例
我们可以在 ADO.NET 中使用 LINQ。 SQLiteDataAdapter 是 System.Data.DataSet 和数据源之间的桥梁。
using System.Data.SQLite;
using System.Data;
string cs = @"URI=file:test.db";
using var ds = new DataSet();
using var con = new SQLiteConnection(cs);
using var sad = new SQLiteDataAdapter("SELECT * FROM cars", con);
sad.Fill(ds);
var res = from dt in ds?.Tables[0]?.AsEnumerable()
select new
{
Id = dt.Field<long>("id"),
Name = dt.Field<string>("name"),
Price = dt.Field<int>("price"),
};
foreach (var e in res)
{
Console.WriteLine(e);
}
Console.WriteLine(res.Count());
SQLiteDataAdapter 用于填充 DataSet,我们从中创建一个可枚举对象。 在该可枚举对象上执行 LINQ 查询。
$ dotnet run
{ Id = 1, Name = Audi, Price = 52642 }
{ Id = 2, Name = Mercedes, Price = 57127 }
{ Id = 3, Name = Skoda, Price = 9000 }
{ Id = 4, Name = Volvo, Price = 29000 }
{ Id = 5, Name = Bentley, Price = 350000 }
{ Id = 6, Name = Citroen, Price = 21000 }
{ Id = 7, Name = Hummer, Price = 41400 }
{ Id = 8, Name = Volkswagen, Price = 21600 }
8
来源
在本文中,我们使用了 ADO.NET。
作者
列出所有 C# 教程。