ищу альтернативный путь для этого случая переключателя или любого другого решения - PullRequest
0 голосов
/ 25 января 2020

Я выполняю операцию обновления базы данных и обновляю некоторые поля на основе типа, передаваемого во внутренний метод с помощью оператора switch case, на данный момент у него 4 оператора 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();
    }

, и это будет enum

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;
  }

может кто-нибудь подсказать, как преобразовать этот случай переключения в альтернативный тип с ключом пара значений или с типами, которые были бы очень благодарны мне.

большое спасибо заранее

Обновление : я ищу вид нижеприведенного метода, я использую точку net ядро ​​с EF core

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

Ответы [ 2 ]

2 голосов
/ 25 января 2020

Вместо того, чтобы передавать параметр MasterSectionEnum, измените ваш метод так, чтобы он принимал параметр типа. Затем просто используйте этот тип generi c в одном вызове UpdateRevision.

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

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

}

Если все допустимые типы SectionType имеют общий интерфейс или являются производными от одного класса, тогда вы можете взять далее, добавьте ограничение к SectionType и избегайте необходимости обрабатывать некорректные типы во время выполнения.


Редактировать:

Так что SetRequestStage не может быть обобщенным c да? Ну, склонность сделать его обобщенным c проистекает из того факта, что он зависит от UpdateRevision, который является обобщенным c. Это в свою очередь зависит от DbContext.Set(). И вы используете его c версию. Но хорошая новость заключается в том, что, похоже, существует non-generi c версия , которая принимает переменную типа в качестве параметра. Итак:

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);
    ....

}

Я не знаю, как выглядит ваш пользовательский интерфейс. Но, в общем случае:

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]);

}

Извините, если синтаксис последнего не совсем правильный. Но вы поняли.

0 голосов
/ 25 января 2020

Вы можете попробовать это:

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
...