.NET Core 2.2 EF Core:工作单元+仓储模式下为部分模型实现特定操作
实现针对部分模型的专用仓储(CountRepository)
Absolutely, you can create a dedicated repository class to handle specific operations only for your TypeA, TypeB, and TypeC models (all inheriting from BaseCountEntity). This is a clean way to avoid repeating identical filter logic across multiple repositories and keeps your code focused on single responsibilities.
Here's how to implement this in your existing .NET Core 2.2 + EF Core setup:
1. 完善 ICountRepository 接口
首先定义统计操作的契约,你可以结合泛型方法(处理所有BaseCountEntity子类的共享逻辑)和类型专属方法(如果单个模型需要自定义逻辑):
// Solution.DAL.Core.Repositories.ICountRepository.cs using Solution.EFProject.Models; using System.Collections.Generic; public interface ICountRepository { // 泛型方法:处理所有继承BaseCountEntity的模型 IEnumerable<T> GetFilteredCounts<T>(DateTime countDate, long xCountThreshold) where T : BaseCountEntity; // 可选:类型专属方法(如果需要为单个模型添加自定义过滤) IEnumerable<TypeA> GetFilteredTypeACounts(DateTime countDate, long xCountThreshold); IEnumerable<TypeB> GetFilteredTypeBCounts(DateTime countDate, long xCountThreshold); IEnumerable<TypeC> GetFilteredTypeCCounts(DateTime countDate, long xCountThreshold); }
2. 实现 CountRepository
这个类将专注于统计相关逻辑,不需要继承通用的Repository<T>(因为它是专用处理器,而非全量CRUD仓储):
// Solution.DAL.Persistence.Repositories.CountRepository.cs using Microsoft.EntityFrameworkCore; using Solution.EFProject.Models; using System.Collections.Generic; using System.Linq; public class CountRepository : ICountRepository { private readonly DbContext _context; public CountRepository(DbContext context) { _context = context; } // 泛型实现:处理共享过滤逻辑 public IEnumerable<T> GetFilteredCounts<T>(DateTime countDate, long xCountThreshold) where T : BaseCountEntity { return _context.Set<T>() .Where(e => e.CountDate == countDate && e.XCount >= xCountThreshold) .AsEnumerable(); } // 类型专属实现(可在这里添加模型特有的过滤条件) public IEnumerable<TypeA> GetFilteredTypeACounts(DateTime countDate, long xCountThreshold) { return _context.Set<TypeA>() .Where(e => e.CountDate == countDate && e.XCount >= xCountThreshold) // 可添加TypeA专属过滤,比如 e.ACount > 0 .AsEnumerable(); } public IEnumerable<TypeB> GetFilteredTypeBCounts(DateTime countDate, long xCountThreshold) { return _context.Set<TypeB>() .Where(e => e.CountDate == countDate && e.XCount >= xCountThreshold) .AsEnumerable(); } public IEnumerable<TypeC> GetFilteredTypeCCounts(DateTime countDate, long xCountThreshold) { return _context.Set<TypeC>() .Where(e => e.CountDate == countDate && e.XCount >= xCountThreshold) .AsEnumerable(); } }
3. 集成到 IUnitOfWork
更新工作单元的接口和实现,加入ICountRepository,让业务层可以和其他仓储一起访问它:
更新接口
// Solution.DAL.Core.IUnitOfWork.cs public interface IUnitOfWork { ITypeARepository TypeARepository { get; } ITypeBRepository TypeBRepository { get; } ITypeCRepository TypeCRepository { get; } IOtherModelRepository OtherModelRepository { get; } ICountRepository CountRepository { get; } // 添加这一行 int Complete(); }
更新实现
// Solution.DAL.Persistence.Repositories.UnitOfWork.cs public class UnitOfWork : IUnitOfWork { private readonly DbContext _context; public ITypeARepository TypeARepository { get; } public ITypeBRepository TypeBRepository { get; } public ITypeCRepository TypeCRepository { get; } public IOtherModelRepository OtherModelRepository { get; } public ICountRepository CountRepository { get; } // 添加这个属性 public UnitOfWork(DbContext context, ITypeARepository typeARepo, ITypeBRepository typeBRepo, ITypeCRepository typeCRepo, IOtherModelRepository otherModelRepo, ICountRepository countRepo) { _context = context; TypeARepository = typeARepo; TypeBRepository = typeBRepo; TypeCRepository = typeCRepo; OtherModelRepository = otherModelRepo; CountRepository = countRepo; // 初始化统计仓储 } public int Complete() { return _context.SaveChanges(); } public void Dispose() { _context.Dispose(); } }
4. 注册依赖
别忘了在Startup.cs中将ICountRepository注册到DI容器:
services.AddScoped<ICountRepository, CountRepository>();
5. 业务逻辑中使用示例
这是在服务类中使用的方式:
public class CountService { private readonly IUnitOfWork _unitOfWork; public CountService(IUnitOfWork unitOfWork) { _unitOfWork = unitOfWork; } // 使用泛型方法处理任意BaseCountEntity模型 public IEnumerable<TypeA> GetTypeAHighCounts(DateTime targetDate) { return _unitOfWork.CountRepository.GetFilteredCounts<TypeA>(targetDate, 1000); } // 使用类型专属方法处理自定义逻辑 public IEnumerable<TypeB> GetTypeBValidCounts(DateTime targetDate) { return _unitOfWork.CountRepository.GetFilteredTypeBCounts(targetDate, 500); } }
这种方案的核心优势
- 代码复用:无需在
TypeARepository、TypeBRepository等多个仓储中重复编写CountDate/XCount的过滤逻辑 - 单一职责:
CountRepository只专注于统计相关操作,其他仓储负责各自模型的全量CRUD - 扩展性:可根据需求随时添加更多泛型或类型专属方法
内容的提问来源于stack exchange,提问作者ablaze
相关产品推荐
相关产品推荐

