--- applyTo: "src/Fengling.Member.Infrastructure/Repositories/*.cs" --- # 仓储开发指南 ## 开发原则 ### 必须 - **仓储定义**: - 每个聚合根对应一个仓储。 - 接口必须继承 `IRepository`。 - 实现必须继承 `RepositoryBase`。 - 接口和实现定义在同一个文件中。 - **注册**:仓储类会被自动注册到依赖注入容器中,无需手动注册。 - **实现**: - 使用 `DbContext` 属性访问当前的 `DbContext` 实例。 - 在自定义仓储方法中,使用 `DbContext.EntitySetName` 访问具体的 DbSet。 ### 必须不要 - **冗余方法**:默认基类已经实现了一组常用方法,如无必要,尽量不要定义新的仓储方法。 - **重复引用**:无需重复添加 `Microsoft.EntityFrameworkCore` 引用(已在 `GlobalUsings.cs` 中定义)。 ## 文件命名规则 - 仓储接口和实现应放置在 `src/Fengling.Member.Infrastructure/Repositories/` 目录下。 - 文件名格式为 `{AggregateName}Repository.cs`。 ## 代码示例 **文件**: `src/Fengling.Member.Infrastructure/Repositories/AdminUserRepository.cs` ```csharp using Fengling.Member.Domain.AggregatesModel.AdminUserAggregate; namespace Fengling.Member.Infrastructure.Repositories; // 接口和实现定义在同一文件中 public interface IAdminUserRepository : IRepository { /// /// 根据用户名获取管理员 /// Task GetByUsernameAsync(string username, CancellationToken cancellationToken = default); /// /// 检查用户名是否存在 /// Task UsernameExistsAsync(string username, CancellationToken cancellationToken = default); } public class AdminUserRepository(ApplicationDbContext context) : RepositoryBase(context), IAdminUserRepository { public async Task GetByUsernameAsync(string username, CancellationToken cancellationToken = default) { return await DbContext.AdminUsers.FirstOrDefaultAsync(x => x.Username == username, cancellationToken); } // ...existing code... public async Task UsernameExistsAsync(string username, CancellationToken cancellationToken = default) { return await DbContext.AdminUsers.AnyAsync(x => x.Username == username, cancellationToken); } } ``` ## 框架默认实现的方法 框架的 `IRepository` 和 `IRepository` 接口已实现以下方法,无需在自定义仓储中重复实现: ### 基础操作 - `IUnitOfWork UnitOfWork` - 获取工作单元对象 - `TEntity Add(TEntity entity)` - 添加实体 - `Task AddAsync(TEntity entity, CancellationToken cancellationToken = default)` - 异步添加实体 - `void AddRange(IEnumerable entities)` - 批量添加实体 - `Task AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default)` - 异步批量添加实体 - `void Attach(TEntity entity)` - 附加实体(状态设为未更改) - `void AttachRange(IEnumerable entities)` - 批量附加实体 - `TEntity Update(TEntity entity)` - 更新实体 - `Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default)` - 异步更新实体 - `bool Delete(Entity entity)` - 删除实体 - `Task DeleteAsync(Entity entity)` - 异步删除实体 ### 主键操作(仅 IRepository) - `TEntity? Get(TKey id)` - 根据主键获取实体 - `Task GetAsync(TKey id, CancellationToken cancellationToken = default)` - 异步根据主键获取实体 - `int DeleteById(TKey id)` - 根据主键删除实体 - `Task DeleteByIdAsync(TKey id, CancellationToken cancellationToken = default)` - 异步根据主键删除实体