深入解析. NET ORM 利器:RepoDB 及其实践使用

RepoDB 是什么?

在 . NET 生态中,我们常见两类 ORM(对象-关系映射)库:一类是“宏”型全功能 ORM(如 Entity Framework),另一类是“微”型轻量库(如 Dapper)。RepoDB 就是定位在这两者之间的一款「混合型」ORM。
它旨在:保留微型 ORM 那种直接、清晰、控制性强的优点,同时提供近似于全功能 ORM 的通用操作能力。官网指出,它“桥接了微型 ORM 和宏型 ORM 之间的差距”。

RepoDB 支持的数据库包括 SQL Server、MySQL、PostgreSQL、SQLite 等。

为什么选择 RepoDB?核心优势

  1. 高性能、低开销:它在内部缓存 compiled expression、属性映射、SQL 语句生成等,从而减少重复开销。

  2. 简单易用:多数操作是扩展方法直接作用于 IDbConnection,对习惯 ADO.NET 或 Dapper 的开发者比较友好。

  3. 功能覆盖广、灵活切换:你既可以直接执行 SQL,也可以使用更高层的 Query/Insert/Update 方法;还支持批量(Bulk)操作、缓存、映射、二级缓存等。

  4. 跨数据库支持好:多种关系型数据库支持,一致性比较强。

安装与初始配置

以 SQL Server 为例:

1. 在 NuGet 中安装包:

Install-Package RepoDb.SqlServer

如果用到批量操作,还可安装:

Install-Package RepoDb.SqlServer.BulkOperations

2. 在程序启动或初始化时调用配置:

GlobalConfiguration
    .Setup()
    .UseSqlServer();

3. 定义你的实体模型(POCO)对应数据库表。示例:

public class Person
{
    public long Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public DateTime CreatedDateUtc { get; set; }
}

4. 使用 IDbConnection 对象连接数据库,注意保证连接可用(如 EnsureOpen())等。

基础 CRUD 操作示例

下面基于上面的 Person 模型展示一些常用操作。

插入(Insert)

using (var connection = new SqlConnection(connectionString))
{
    var person = new Person
    {
        Name = "John Doe",
        Age = 54,
        CreatedDateUtc = DateTime.UtcNow
    };
    var id = connection.Insert(person);
}

此时 id 将返回自增主键值,同时 person.Id 也会被设置回实体。

查询(Query)

using (var connection = new SqlConnection(connectionString))
{
    var person = connection.Query<Person>(p => p.Id == 1);
    var all = connection.QueryAll<Person>();
}

Query 方法支持表达式过滤,QueryAll 获取所有记录。

更新/合并(Update/Merge)

Merge 方法支持“如果存在则更新,否则插入”的逻辑。例如:

var person = new Person
{
    Id = 1,
    Name = "John Doe",
    Age = 57,
    CreatedDateUtc = DateTime.UtcNow
};
using (var connection = new SqlConnection(connectionString))
{
    var id = connection.Merge(person);
}

也可使用 qualifiers 参数指定其他列作为判定条件。

删除(Delete)

using (var connection = new SqlConnection(connectionString))
{
    var deletedRows = connection.Delete<Person>(10045);
    var deletedByName = connection.Delete<Person>(p => p.Name == "John Doe");
}

也支持 DeleteAll 和传入主键数组。

批量操作、缓存与高级特性

批量操作(Bulk)

当面对大量数据插入/更新/合并时,使用 BulkInsert、BulkMerge 等方法可显著提高效率。示例(以 PostgreSQL 为例):

var people = GetPeople(100);
using (var connection = new NpgsqlConnection(connectionString))
{
    var affected = connection.BulkInsert(people);
}

BulkMerge、BulkUpdate 等同理。

缓存支持(二级缓存)

RepoDB 支持缓存机制,例如你可以在 Query 时指定 cacheKey 和 cache 对象,从而启用缓存:

var cache = CacheFactory.GetMemoryCache();
using (var connection = new SqlConnection(connectionString).EnsureOpen())
{
    var products = connection.Query<Product>(cacheKey:"products", cache:cache);
}

这样对热点数据、读多写少场景能提升性能。

映射、属性处理、类型映射等

可以通过映射器(Mapper)机制,定制实体属性与数据库字段之间的映射。如 FluentMapper、PropertyHandler 等。 RepoDB

实际项目中的使用建议

  • 在中型项目中,当你不需要 Entity Framework 那种完整的上下文追踪、变更检测功能,但又希望比 Dapper 写原生 SQL 更加简洁时,RepoDB 是一个不错的选择。

  • 对于数据量较大、需要批量导入/更新场景,RepoDB 的 Bulk 功能显著。

  • 在需要跨数据库(比如既有 SQL Server、SQLite、MySQL)维护通用代码时,其多数据库支持也加分。

  • 注意:如果你的项目强烈依赖 Change Tracking、LINQ Provider 、复杂导航属性、迁移工具(Migrations)等功能,RepoDB 相比 Entity Framework 可能略弱。

  • 在使用缓存、批量操作时,务必考虑事务、一致性、缓存过期策略等,避免“缓存脏数据”或“批量操作失败后回滚不完整”。

  • 在启动阶段尽量“预热”关键查询、避免首次访问延迟,因为其内部的 AOT 表达式编译可能会带来首次调用的开销。

总结

如果你希望在 . NET 中获得一种“既比 Dapper 更高层、又比 Entity Framework 更轻量”的数据访问方案,那么 RepoDB 值得尝试。它在性能、灵活性与易用性之间取得了不错的平衡。本文从其定义、优势、安装配置、基础操作到高级特性进行了较为完整的介绍。下一步可尝试在你自己的项目中做一个小模块试用,以评估其与当前数据访问架构的契合度。

评论