跳到主要内容
版本:3.0

Repository 层

这一层就是把数据访问收进去。

先按最直接的理解来用:

  • 查库放这里
  • 落库放这里
  • FreeSql 的使用也收在这里

业务规则别写在这里。

这一层通常放什么

最常见的有:

  • IDbSource 的实现
  • Entity
  • Repository
  • 多表查询需要的映射对象

一个常见结构例如:

Repository
├── Entities
├── View
├── MappingDatas
└── Repositories

DbSource 是干什么的

先建一个实现 IDbSource 的类,把当前数据库连接标识出来。

public class AegisDb : IDbSource
{
public AegisDb(IFreeSql<AegisDb> sqlClient)
{
SqlClient = sqlClient;
}

public IFreeSql<AegisDb> SqlClient { get; }
}

这个类不用写复杂逻辑,它主要是给当前数据库连接一个明确的入口。

Entity 怎么写

Entity 是数据库表对应的实体。

常见写法:

  • 类名以 Entity 结尾
  • [Table] 指定表名
  • 主键用 [Column(IsPrimary = true)]

例如:

[Table(Name = "User")]
public class UserEntity
{
[Column(IsPrimary = true)]
public long Id { get; set; }

public string Name { get; set; }
}

Repository 怎么写

最常见的仓储类,就是继承 BaseRepository<TEntity, TId>

public class UserRepository : BaseRepository<UserEntity, long>
{
public UserRepository(IFreeSql<AegisDb> fsql) : base(fsql)
{
}

public Task<UserEntity> GetByIdAsync(long id)
{
return this.Where(x => x.Id == id).FirstAsync();
}
}

第一版项目里,单表增删改查通常写到这里就够了。

Service 和 Repository 的边界

这一条别混:

  • Repository 负责数据访问
  • Service 负责业务流程

也就是说:

  • Service 可以调 Repository
  • Service 不要直接去碰 IFreeSql

什么时候需要 MappingData

如果是简单单表,Entity 通常就够。
如果是多表联查、结果又不适合直接回 DTO,可以先在 Repository 层建一个中间映射对象。

这类对象通常只服务于查询结果整理,不承担业务逻辑。

这一层最容易踩的坑

  • 在 Repository 里写业务判断
  • 在 Service 里直接查库
  • Entity 和 DTO 混着用
  • 仓储类越过边界去做接口层拼装

先做到什么程度就够

第一版项目里,这一层先做到下面这样就够了:

  • 能定义 DbSource
  • 能定义一个 Entity
  • 能写一个 Repository
  • 能让 Service 通过 Repository 查出一条数据

等第一版稳定了,再继续补复杂查询、分页对象、多表映射这些东西。