在C#中,有多种常用的数据库访问技术,这些技术为开发者提供了与各种数据库进行交互的能力。以下是其中一些主要的数据库访问技术:
-
ADO.NET (ActiveX Data Objects .NET)
ADO.NET 是 Microsoft 提供的 .NET Framework 中的一个数据访问技术。它提供了一组与数据源进行交互的类,包括
SqlConnection
、SqlCommand
、SqlDataReader
和SqlDataAdapter
等。ADO.NET 支持断开连接的数据访问,这意味着开发者可以在不保持与数据库连接的情况下处理数据。它支持多种数据库,包括 SQL Server、Oracle、MySQL 等。 -
Entity Framework (EF)
Entity Framework 是一个对象关系映射器 (ORM),它允许开发者使用 .NET 对象与数据库进行交互,而无需编写大量的数据访问代码。EF 提供了数据模型(通常是 C# 类)与数据库表之间的映射,并提供了 LINQ(Language Integrated Query)查询功能。EF 有几个版本,包括 EF 6.x(也称为 EF 经典)和 EF Core(跨平台、轻量级的版本)。
-
Dapper
Dapper 是一个轻量级的对象关系映射器,它专注于简化数据库访问。与 Entity Framework 不同,Dapper 是一个非常薄的层,它仅仅将查询结果映射到 POCO(Plain Old CLR Objects)对象上。由于它的轻量级特性,Dapper 通常比 EF 更快,并且提供了更多的灵活性。
-
NHibernate
NHibernate 是一个流行的 .NET ORM 工具,它基于 Java 的 Hibernate 项目。NHibernate 提供了丰富的功能,如一级和二级缓存、延迟加载、事务管理等。它支持多种数据库,并允许开发者使用 HQL(Hibernate Query Language)或 LINQ 进行查询。
-
Dapper.Contrib
Dapper.Contrib 是一个扩展库,它为 Dapper 提供了额外的功能,如基本的 CRUD(创建、读取、更新、删除)操作。使用 Dapper.Contrib,开发者可以更容易地对数据库进行基本的增删改查操作。
-
LLBLGen Pro
LLBLGen Pro 是一个商业 ORM 工具,它提供了丰富的功能和强大的性能。它支持多种数据库,并允许开发者使用自己的查询语言或 LINQ 进行查询。此外,LLBLGen Pro 还提供了代码生成器,可以自动生成数据访问代码和模型。
这些数据库访问技术各有优缺点,开发者应根据项目的具体需求和技术栈选择合适的工具。
【ADO.NET】
以下是一个使用SqlConnection
、SqlCommand
和SqlDataReader
的示例,用于从数据库中读取数据:
首先,确保你已经安装了SQL Server数据库,并且有一个可以连接的数据库实例和表。在这个例子中,我们将假设你有一个名为MyDatabase
的数据库和一个名为Customers
的表。
using System;
using System.Data.SqlClient; // 引入SqlClient命名空间
class Program
{
static void Main()
{
string connectionString = "Server=localhost;Database=MyDatabase;User Id=your_username;Password=your_password;";
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open(); // 打开数据库连接
string sql = "SELECT * FROM Customers"; // 定义SQL查询
using (SqlCommand command = new SqlCommand(sql, connection))
{
using (SqlDataReader reader = command.ExecuteReader()) // 执行查询并获取SqlDataReader
{
while (reader.Read()) // 逐行读取结果
{
Console.WriteLine("{0} {1}", reader["FirstName"], reader["LastName"]);
// 或者,如果你知道列的类型和名称,可以使用索引或列名(如int, string等)
// 例如: int id = reader.GetInt32(0);
// string firstName = reader.GetString(1);
}
}
}
}
}
catch (SqlException e)
{
Console.WriteLine(e.ToString());
}
Console.ReadLine(); // 保持控制台窗口打开
}
}
【EF Core】
步骤1:创建数据模型(Customer.cs)
public class Customer
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
// ... 其他属性 ...
}
步骤2:创建DbContext类(ApplicationDbContext.cs)
using Microsoft.EntityFrameworkCore;
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Customer> Customers { get; set; }
// ... 其他DbSet属性 ...
}
步骤3:配置Entity Framework Core(在Program.cs中)
你需要在Program.cs
文件的Main
方法中配置Entity Framework Core,并设置数据库连接字符串。这通常是在Startup.cs
(对于ASP.NET Core应用程序)或程序的主入口点中完成的。
对于控制台应用程序,你可以在Main
方法中这样做:
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
class Program
{
static void Main(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseSqlServer("Server=localhost;Database=MyDatabase;User Id=your_username;Password=your_password;");
using (var context = new ApplicationDbContext(optionsBuilder.Options))
{
// 确保数据库已创建(如果使用的是Code First)
context.Database.EnsureCreated();
// 查询数据库中的Customer数据
var customers = context.Customers.ToList();
foreach (var customer in customers)
{
Console.WriteLine($"{customer.FirstName} {customer.LastName}");
}
}
Console.ReadLine();
}
}
请注意,上述代码中的连接字符串 "Server=localhost;..."
需要替换为你自己的数据库连接信息。
此外,如果你是在ASP.NET Core项目中工作,配置通常会在Startup.cs
文件的ConfigureServices
方法中进行。
注意:在这个例子中,我们使用了EnsureCreated
方法来确保数据库和表被创建(如果它们还不存在)。在开发环境中,这是一个方便的方法,但在生产环境中,你可能希望使用迁移(Migrations)来管理数据库架构的更改。
【Dapper】
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Dapper;
class Program
{
static void Main(string[] args)
{
string connectionString = "Server=localhost;Database=MyDatabase;User Id=your_username;Password=your_password;";
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
string sql = "SELECT * FROM Customers"; // 假设你有一个名为Customers的表
// 使用Dapper的Query<T>方法查询数据,其中T是你的数据模型类型
var customers = connection.Query<Customer>(sql).ToList();
foreach (var customer in customers)
{
Console.WriteLine("{0} {1}", customer.FirstName, customer.LastName);
}
}
Console.ReadLine(); // 保持控制台窗口打开
}
}
// 假设你有一个与数据库表结构对应的Customer类
public class Customer
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
// ... 其他属性 ...
}
【NHibernate】
NHibernate 是一个面向对象的数据库持久化框架,它允许你使用 .NET 对象来映射到数据库中的表,并提供了查询和操作这些对象的方法。以下是一个使用 NHibernate 访问数据库的基本代码实例:
首先,你需要安装 NHibernate 的 NuGet 包,以及你可能需要的数据库驱动(例如,对于 SQL Server,你可能需要 System.Data.SqlClient
)。
然后,你需要定义你的数据模型(通常是 POCOs,Plain Old CLR Objects),以及这些模型到数据库表的映射。NHibernate 使用 XML 文件或 Fluent NHibernate(一种基于 C# 的映射方式)来定义映射。
这里是一个简单的例子,它展示了如何定义数据模型、映射,以及如何使用 NHibernate 会话(Session)来查询数据库。
1. 定义数据模型(Customer.cs)
public class Customer
{
public virtual int Id { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
// ... 其他属性 ...
}
2. 定义映射(Customer.hbm.xml)
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="YourNamespace.Customer, YourAssembly" table="Customers">
<id name="Id" column="CustomerId">
<generator class="native" />
</id>
<property name="FirstName" column="FirstName" />
<property name="LastName" column="LastName" />
<!-- ... 其他属性映射 ... -->
</class>
</hibernate-mapping>
3. 配置 NHibernate(hibernate.cfg.xml)
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">Server=localhost;Database=MyDatabase;User Id=your_username;Password=your_password;</property>
<property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<mapping resource="YourNamespace.Customer.hbm.xml" />
<!-- ... 其他映射文件 ... -->
</session-factory>
</hibernate-configuration>
4. 使用 NHibernate 会话查询数据库(Program.cs)
using NHibernate;
using NHibernate.Cfg;
using System;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
// 配置 NHibernate
var configuration = new Configuration().Configure(); // 默认从 hibernate.cfg.xml 加载配置
// 创建一个 SessionFactory 实例(通常作为单例管理)
var sessionFactory = configuration.BuildSessionFactory();
// 打开一个 Session
using (var session = sessionFactory.OpenSession())
{
// 使用 HQL(Hibernate Query Language)或 Criteria API 进行查询
var customers = session.QueryOver<Customer>().List();
foreach (var customer in customers)
{
Console.WriteLine("{0} {1}", customer.FirstName, customer.LastName);
}
}
// 关闭 SessionFactory(如果它是手动创建的,并且不是单例)
// sessionFactory.Close();
Console.ReadLine(); // 保持控制台窗口打开
}
}
请注意,NHibernate 的配置和映射文件通常放在项目的适当位置,并且需要根据你的数据库和应用程序进行相应的修改。此外,sessionFactory.Close();
通常不需要在上面的代码示例中调用,因为如果你使用依赖注入容器或单例模式来管理 SessionFactory
,那么它应该在应用程序的生命周期结束时关闭。如果你手动创建并管理 SessionFactory
,那么你应该在不再需要它时关闭它。
【Dapper.Contrib】
Dapper.Contrib 是 Dapper 的一个扩展库,它为常见的 CRUD(增删改查)操作提供了简单的 API。使用 Dapper.Contrib,你可以避免写重复的 SQL 语句,并且它会自动处理对象到数据库表之间的映射。
以下是一个使用 Dapper.Contrib 访问数据库的代码实例:
首先,你需要安装 Dapper 和 Dapper.Contrib 的 NuGet 包。你可以通过 NuGet 包管理器或 .csproj
文件中的 PackageReference
来安装它们。
安装 NuGet 包后,你可以按照以下步骤编写代码:
- 定义你的数据模型(例如
Customer
类)。 - 配置你的数据库连接字符串。
- 使用 Dapper.Contrib 的扩展方法来执行 CRUD 操作。
1. 定义数据模型(Customer.cs)
public class Customer
{
public int Id { get; set; } // 假设数据库中的主键是 Id
public string FirstName { get; set; }
public string LastName { get; set; }
// ... 其他属性 ...
}
2. 配置数据库连接字符串(通常在 appsettings.json 或其他配置文件中)
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=MyDatabase;User Id=your_username;Password=your_password;"
}
}
3. 使用 Dapper.Contrib 访问数据库(Program.cs)
using System;
using System.Configuration;
using System.Data.SqlClient;
using Dapper;
using Dapper.Contrib.Extensions;
class Program
{
static void Main(string[] args)
{
// 从配置文件中获取连接字符串
string connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
// 插入数据
var newCustomer = new Customer { FirstName = "John", LastName = "Doe" };
int insertedId = connection.Insert(newCustomer); // 假设 Id 是自增的
Console.WriteLine("New customer inserted with ID: " + insertedId);
// 查询数据
var customer = connection.Get<Customer>(insertedId); // 根据 Id 查询
Console.WriteLine("Customer Name: " + customer.FirstName + " " + customer.LastName);
// 更新数据
customer.FirstName = "Jane";
connection.Update(customer); // 更新刚才插入的 customer
// 删除数据
connection.Delete(customer); // 删除刚才更新的 customer
}
Console.ReadLine(); // 保持控制台窗口打开
}
}
注意:
- 在上面的示例中,我们假设
Id
属性是数据库表的主键,并且是自增的。如果不是这样,你可能需要手动设置Id
的值或在插入时忽略它。 - 你需要确保
Customer
类的属性名与数据库表中的列名相匹配,或者你可以使用Dapper.Contrib.Extensions
中的属性(如[Key]
、[Computed]
、[ExplicitKeys]
等)来明确指定映射。 - 如果你使用的是 .NET Core 或 .NET 5/6/7 等较新的框架,你可能需要使用不同的方式来读取配置文件中的连接字符串,例如使用
IConfiguration
接口。 - 请确保你的数据库表已经存在,并且其结构与
Customer
类相匹配。Dapper.Contrib 不会为你创建表或管理数据库模式。
【LLBLGen Pro】
LLBLGen Pro 是一个流行的对象关系映射 (ORM) 工具,它允许开发人员从数据库模式生成 C# 或 VB.NET 实体类以及数据访问代码。以下是使用 LLBLGen Pro 生成的代码来访问数据库的一个基本示例。
首先,你需要使用 LLBLGen Pro 工具从数据库模式生成代码。这通常包括实体类、数据访问类(如 DataAccessAdapters、EntityClasses 和 EntityCollections)以及一些辅助类和接口。
假设你已经生成了代码,并且你有一个名为 Customer
的实体类和一个对应的数据访问适配器(如 CustomerEntityFactory
和 CustomerDataAdapter
)。以下是一个使用这些类来访问数据库的例子:
using MyNamespace.EntityClasses; // 假设这是你的实体类所在的命名空间
using MyNamespace.DataAccess; // 假设这是你的数据访问类所在的命名空间
// ...
// 创建一个新的数据访问适配器实例(这通常是单例的)
var adapter = new DataAccessAdapter();
// 使用数据访问适配器获取 Customer 实体工厂
var customerFactory = new CustomerEntityFactory(adapter);
// 创建一个新的 Customer 实体实例
var newCustomer = new CustomerEntity();
newCustomer.FirstName = "John";
newCustomer.LastName = "Doe";
// 保存新的 Customer 实体到数据库
long newCustomerId = adapter.SaveEntity(newCustomer, true); // 第二个参数指示是否应该执行插入操作(如果 ID 为 0)
// 查询 Customer 实体
var predicate = new PredicateExpression(CustomerFields.Id == newCustomerId);
var fetchedCustomer = new CustomerCollection().GetMulti(adapter, predicate).FirstOrDefault();
if (fetchedCustomer != null)
{
Console.WriteLine("Customer Name: " + fetchedCustomer.FirstName + " " + fetchedCustomer.LastName);
// 更新 Customer 实体
fetchedCustomer.FirstName = "Jane";
adapter.SaveEntity(fetchedCustomer, false); // 第二个参数指示是否应该检查是否应该执行更新操作(基于实体状态)
}
// ...
// 在应用程序结束时,确保关闭和释放资源(如果适配器不是单例)
// adapter.Dispose();
请注意,上述代码是一个简化的示例,并且可能需要根据你实际生成的代码和使用的 LLBLGen Pro 版本进行调整。特别是,DataAccessAdapter
、CustomerEntityFactory
、CustomerEntity
、CustomerFields
和 PredicateExpression
的实际名称和用法可能会根据你的数据库模式、配置和 LLBLGen Pro 的版本而有所不同。
此外,请确保在尝试访问数据库之前已经正确配置了数据库连接字符串,并且数据库是可访问的。这些配置通常在 LLBLGen Pro 的项目属性或生成的配置文件中进行设置。