LinqToDB 是一个 C# 的开源库,用于简化数据库访问。它结合了 LINQ(Language Integrated Query)的语法和数据库操作,提供了一种直观且高效的方式来与数据库进行交互。
它支持多种数据库,包括 SQL Server、MySQL、PostgreSQL、SQLite、Oracle 等。
-
基于 LINQ 查询:
- LinqToDB 允许你使用 LINQ 语法来编写查询。
-
轻量级和高性能:
- LinqToDB 以轻量级和高性能著称。它的设计目标是提供尽可能高效的查询生成和执行,并最小化运行时的开销。
-
无须使用 ORM 映射:
- 与像 Entity Framework 这样的 ORM 框架不同,LinqToDB 不需要使用复杂的映射配置。可以直接使用数据库表对应的类来执行查询和操作。
-
跨数据库支持:
- LinqToDB 支持多种数据库系统,这使得应用程序可以更容易地在不同的数据库间迁移。
-
可扩展性:
- LinqToDB 允许你自定义查询生成逻辑和 SQL 生成,提供了灵活性来适应不同的需求。
优点
- 高效性:LinqToDB 的查询生成和执行性能较高,适合需要高性能的应用场景。
- 灵活性:不依赖 ORM 映射,开发者可以灵活控制 SQL 查询,适用于对数据库访问有特定要求的项目。
- 易用性:使用 LINQ 语法编写查询,开发者可以利用 C# 熟悉的语法进行数据库操作。
- 支持多种数据库:能够支持多种数据库引擎,易于跨数据库平台开发。
缺点
- 缺乏 ORM 功能:对于需要复杂映射和关系管理的场景,LinqToDB 的功能可能不够全面。例如,它不提供与实体关系映射相关的功能,如级联删除、关系导航属性等。
-
安装 NuGet 包:
Install-Package linq2db
-
定义数据库上下文:
LinqToDB 需要定义一个数据库上下文类,继承自LinqToDB.Data.DataConnection
。using LinqToDB; using LinqToDB.Data; public class MyDatabase : DataConnection { public MyDatabase() : base("MyDatabaseConnectionString") { } public ITable<Customer> Customers => GetTable<Customer>(); }
-
定义实体类:
实体类映射到数据库表。你可以通过属性来定义列映射。using LinqToDB.Mapping; [Table(Name = "Customers")] public class Customer { [PrimaryKey, Identity] public int Id { get; set; } [Column(Name = "Name"), NotNull] public string Name { get; set; } [Column(Name = "Email"), Nullable] public string Email { get; set; } }
-
[Nullable]
- 表示该列允许
NULL
值。
[Column(Name = "Email"), Nullable] public string Email { get; set; }
- 表示该列允许
-
[NotNull]
- 表示该列不允许
NULL
值。
[Column(Name = "Name"), NotNull] public string Name { get; set; }
- 表示该列不允许
-
[Unique]
- 表示该列值必须是唯一的。
[Column(Name = "Username"), Unique] public string Username { get; set; }
-
[PrimaryKey]
- 标识一个或多个列为主键。
[PrimaryKey] public int Id { get; set; }
-
[Identity]
- 表示该列是自增列。
[Identity] public int Id { get; set; }
-
[Length]
- 指定字符串或二进制数据的最大长度。
[Column(Name = "Name", Length = 100)] public string Name { get; set; }
-
[SkipOnInsert]
- 在插入时跳过该列。
[Column(Name = "CreatedDate"), SkipOnInsert] public DateTime CreatedDate { get; set; }
-
[SkipOnUpdate]
- 在更新时跳过该列。
[Column(Name = "CreatedDate"), SkipOnUpdate] public DateTime CreatedDate { get; set; }
外键和关系映射 [Association]
- 用于定义实体之间的关系(关联),例如一对多或多对一的关系。
//示例:一对多关联
[Table(Name = "Customers")]
public class Customer
{
[PrimaryKey, Identity]
public int Id { get; set; }
[Column(Name = "Name"), NotNull]
public string Name { get; set; }
[Association(ThisKey = "Id", OtherKey = "CustomerId")]
public IEnumerable<Order> Orders { get; set; }
}
[Table(Name = "Orders")]
public class Order
{
[PrimaryKey, Identity]
public int Id { get; set; }
[Column(Name = "OrderDate"), NotNull]
public DateTime OrderDate { get; set; }
[Column(Name = "CustomerId"), NotNull]
public int CustomerId { get; set; }
[Association(ThisKey = "CustomerId", OtherKey = "Id", CanBeNull = false)]
public Customer Customer { get; set; }
}
-
ThisKey
: 当前实体中对应外键的列。 -
OtherKey
: 关联实体中主键对应的列。 -
CanBeNull
: 指定关联是否可以为空。
创建完关联关系后,即可通过访问类上的属性来获取数据库里面的关联数据
执行查询:
使用 LINQ 语法来编写查询,并通过数据库上下文执行。
using(var db = new MyDatabase())
{
var query = from c in db.Customers
where c.Name.StartsWith("A")
select c;
foreach(var customer in query)
{
Console.WriteLine($"ID: {customer.Id}, Name: {customer.Name}");
}
}
插入、更新和删除:
你也可以使用 LinqToDB 进行数据的插入、更新和删除操作。
using(var db = new MyDatabase())
{
// 插入
db.Insert(new Customer { Name = "John Doe", Email = "john@example.com" });
// 更新
db.Customers
.Where(c => c.Name == "John Doe")
.Set(c => c.Email, "newemail@example.com")
.Update();
// 删除
db.Customers
.Where(c => c.Name == "John Doe")
.Delete();
}