如何为不同DbSet<实体类>实现通用方法以消除代码重复?
重复DbSet代码的通用化改造方案
我有一段存在大量重复的代码,希望将其改造为通用方法:
await using (var dbContext = await NoTrackingDbFactory.CreateDbContextAsync()) { switch (ModelType) { case AttributeModel.AttributeType.Certification: var listCerts = await dbContext.Certifications.OrderBy(c => c.Name).ToListAsync(); listModels.AddRange(listCerts.Select(item => new AttributeModel(BlobService, item))); PsuedoAttribute = listCerts.First(); break; case AttributeModel.AttributeType.Interest: HasColors = true; var listInterests = await dbContext.Interests.OrderBy(c => c.Name).ToListAsync(); listModels.AddRange(listInterests.Select(item => new AttributeModel(BlobService, item))); PsuedoAttribute = listInterests.First(); break; case AttributeModel.AttributeType.Skill: var listSkills = await dbContext.Skills.OrderBy(c => c.Name).ToListAsync(); listModels.AddRange(listSkills.Select(item => new AttributeModel(BlobService, item))); PsuedoAttribute = listSkills.First(); break; case AttributeModel.AttributeType.Tag: var listTags = await dbContext.Tags.OrderBy(c => c.Name).ToListAsync(); listModels.AddRange(listTags.Select(item => new AttributeModel(BlobService, item))); PsuedoAttribute = listTags.First(); break; } }我无法解决的是如何为
dbContext.Certifications、dbContext.Interests等DbSet实现通用逻辑。这四个DbSet对应的实体类均继承自同一基类,但它们是不同的DbSet。请问能否实现这样的通用方法?
可以实现,核心思路是通过类型映射+通用方法统一处理不同DbSet,同时兼容特殊分支的定制逻辑,具体实现如下:
步骤1:定义类型映射关系
先建立AttributeModel.AttributeType到对应实体类型的映射,同时记录每个类型对应的DbSet获取方式(假设实体基类名为BaseAttributeEntity):
private static readonly Dictionary<AttributeModel.AttributeType, Func<YourDbContext, DbSet<BaseAttributeEntity>>> _typeToDbSet = new() { { AttributeModel.AttributeType.Certification, ctx => ctx.Certifications.Cast<BaseAttributeEntity>() }, { AttributeModel.AttributeType.Interest, ctx => ctx.Interests.Cast<BaseAttributeEntity>() }, { AttributeModel.AttributeType.Skill, ctx => ctx.Skills.Cast<BaseAttributeEntity>() }, { AttributeModel.AttributeType.Tag, ctx => ctx.Tags.Cast<BaseAttributeEntity>() } };
步骤2:编写通用处理方法
提取重复逻辑到通用方法,单独处理特殊分支的定制逻辑:
private async Task ProcessAttributeType(AttributeModel.AttributeType modelType, YourDbContext dbContext) { // 获取当前类型对应的DbSet var dbSet = _typeToDbSet[modelType](dbContext); // 通用查询与转换逻辑 var entities = await dbSet.OrderBy(e => e.Name).ToListAsync(); listModels.AddRange(entities.Select(item => new AttributeModel(BlobService, item))); PsuedoAttribute = entities.First(); // 处理Interest分支的特殊逻辑 if (modelType == AttributeModel.AttributeType.Interest) { HasColors = true; } }
步骤3:重构原代码
替换原来的switch分支,调用通用方法即可:
await using (var dbContext = await NoTrackingDbFactory.CreateDbContextAsync()) { await ProcessAttributeType(ModelType, dbContext); }
补充说明
- 确保实体基类
BaseAttributeEntity包含Name属性,这样才能在通用逻辑中统一执行OrderBy(e => e.Name)。 - 后续新增
AttributeType时,只需在_typeToDbSet中添加新的映射关系,无需修改核心处理逻辑,符合开闭原则。
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

