寻找此开关盒或任何其他解决方案的替代方法

looking alternative way for this switch case or any other solution

我正在执行数据库更新操作,并根据类型更新一些字段,这些字段被传递给带有 switch case 语句的内部方法,目前它有 4 个 case 语句并且它会变大..

我正在寻找一种方法将此 switch case 转换为具有键值对的字典或任何类型的机制以在方法内部实现。

这是主要方法

  public async Task<MutationResponse> SetRequestStage(string requestStage, Guid requestId, MasterSectionEnum masterSectionEnum)
  {
        var request = _dbContext.Requests.SingleOrDefault(r => r.Id == requestId);
        var rs = _dbContext.RequestStages.SingleOrDefault(rs => rs.Name == requestStage);

        if (rs != null)
        {
            request.RequestStage = rs;

            if (rs.Name == "Approved")
            {
                switch (masterSectionEnum)
                {
                    case MasterSectionEnum.LOCALCODE:
                        await UpdateRevision<LocalCode>(request.DataId).ConfigureAwait(false);
                        break;
                    case MasterSectionEnum.NATIONALCODE:
                        await UpdateRevision<NationalCode>(request.DataId).ConfigureAwait(false);
                        break;
                    case MasterSectionEnum.GUIDELINES:
                        await UpdateRevision<Guideline>(request.DataId).ConfigureAwait(false);
                        break;
                    case MasterSectionEnum.LIBRARYA621:
                        await UpdateRevision<LibraryA621>(request.DataId).ConfigureAwait(false);
                        break;
                    case .....
                    case .....
                    default:
                        throw new ArgumentException($"SetRequestStage Error: invalid MasterSection {masterSectionEnum.ToString()}");
                }
            }
        }
        _dbContext.SaveChanges();
        return new MutationResponse();
    }

这将是枚举

public enum MasterSectionEnum
{
    LOCALCODE,
    NATIONALCODE,
    GUIDELINES,
    SPACETYPE,
    LIBRARYA621 
   // this will grow bigger
}

这将是我从上述方法调用的内部方法

 private async Task UpdateRevision<T>(Guid id) where T : class, IAEIMaster, IRevisionData
 {
        var dbSet = this._dbContext.Set<T>();
        var code = dbSet.SingleOrDefault(c => c.Id == id);
        ......
        ......
        code.Revision = revision;
        code.IsApproved = true;
  }

任何人都可以建议如何将此 switch case 转换为具有键值对或类型的替代类型,我将非常感激。

非常感谢

更新:我正在寻找下面的方法,我正在使用带 EF 核心的点网核心

        var types = new Dictionary<string, string>();
        foreach(var item in types)
        {
            if(item.Key == "enum value")
            {
                await UpdateRevision<item.value>(request.DataId).ConfigureAwait(false);
            }
        }

你可以试试这个:

public enum MasterSectionEnum
{
    LOCALCODE,
    NATIONALCODE
}

public sealed class LocalCode { }
public sealed class NationalCode { }

public sealed class Program
{
    private static readonly Dictionary<MasterSectionEnum, Func<Guid, Task>> Dictionary
        = new Dictionary<MasterSectionEnum, Func<Guid, Task>>();

    static Program()
    {
        Dictionary[MasterSectionEnum.LOCALCODE] = UpdateRevision<LocalCode>;
        Dictionary[MasterSectionEnum.NATIONALCODE] = UpdateRevision<NationalCode>;
    }

    public static async Task SetRequestStage(MasterSectionEnum masterSectionEnum)
    {
        await Dictionary[masterSectionEnum].Invoke(Guid.NewGuid());
    }

    private static Task UpdateRevision<T>(Guid id) where T : class
    {
        Console.WriteLine(typeof(T));
        return Task.CompletedTask;
    }

    public static async Task Main()
    {
        await SetRequestStage(MasterSectionEnum.LOCALCODE);
        await SetRequestStage(MasterSectionEnum.NATIONALCODE);

        Console.ReadKey();
    }
}

结果:

LocalCode
NationalCode

不要传入参数 MasterSectionEnum,而是更改您的方法以接受类型参数。然后只需在 UpdateRevision.

的单个调用中使用该泛型类型
public async Task<MutationResponse> SetRequestStage<SectionType>(
    string requestStage, 
    Guid requestId
) {

    ...
    await UpdateRevision<SectionType>(request.DataId).ConfigureAwait(false);
    ....

}

如果 SectionType 的所有有效类型共享一个接口或派生自同一个 class,那么您可以更进一步,向 SectionType 添加约束,避免在运行时处理错误类型。


编辑:

所以 SetRequestStage 不能是通用的吧?好吧,使它成为通用的倾向源于它依赖于通用的 UpdateRevision 这一事实。这又取决于DbContext.Set()。而且您正在使用它的通用版本。但好消息是它似乎有一个 non-generic version 接受类型变量作为参数。所以:

async Task UpdateRevision<T>(
    Guid id,
    Type t
) where T : class, IAEIMaster, IRevisionData {

    var dbSet = this._dbContext.Set(t);
    ...

}

然后:

public async Task<MutationResponse> SetRequestStage(
    string requestStage, 
    Guid requestId,
    Type SectionType
) {

    ...
    await UpdateRevision(request.DataId, SectionType).ConfigureAwait(false);
    ....

}

我不知道你的UI长什么样。但是,一般来说:

var dic = new Dictionary<MasterSectionEnum, Type> {
    { MasterSectionEnum.LOCALCODE, typeof(LocalCode) },
    { MasterSectionEnum.NATIONALCODE, typeof(NationalCode) },
    ...
};

public async someUiRelatedMethod(
    string reqStage,
    Guid reqId,
    MasterSectionEnum sectionType
) {

    await SetRequestStage(reqStage, reqId, dic[sectionType]);

}

抱歉,如果后者的语法不太正确。但是你明白了。