You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为不同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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 09:57:51