Инициализировать коллекции в ASP.NET Core Controller

У меня есть контроллер, который должен отображать несколько вариантов выбора (выпадающих) с предопределенными значениями.

Я отображаю список записей, каждый Record может иметь предопределенный Theme и соответствуют City из списка предопределенных значений.

У меня в контроллере есть

private IEnumerable<Record> records;
private static IEnumerable<Theme> themes;
private static IEnumerable<City> cities;

private async Task<bool> LoadThemes()
{
    themes = await repository.GetTableEntitiesAsync<Theme>(lang);
    return true;
}

private async Task<bool> LoadCities()
{
    themes = await repository.GetTableEntitiesAsync<City>(lang);
    return true;
}

и действие

public async Task<IActionResult> Index()
{
    // records = from DB, then
    await LoadThemes(); ViewData["themes"] = this.themes;
    await LoadCities(); ViewData["cities"] = this.cities;

    return View(records);
}

public async Task<IActionResult> Edit(string id)
{
    // record => from id, then
    await LoadThemes(); ViewData["themes"] = this.themes;
    await LoadCities(); ViewData["cities"] = this.cities;

    return View(record);
}

Так как я не могу сделать асинхронный конструктор, и я не уверен, проходя через Index Посмотрите, как я могу инициализировать мои "статические" коллекции только один раз?

1 ответ

Вы не должны использовать статическую переменную в этом сценарии. Вместо этого вы просто храните их в локальных переменных.

Посмотреть

<form asp-controller="Index" asp-action="Sample" method="post">
    <select asp-for="Cities" asp-items="@Model.Cities"></select>
    <select asp-for="ThemeId" asp-items="@Model.Themes"></select>
    <button type="submit">Submit</button>
</form>

ViewModel

public class RecordViewModel
{
    public string Id { get; set; }
    public string ThemeId { get; set; }
    public string CityId { get; set; }
    public IList<SelectListItem> Themes { get; set; }            
    public IList<SelectListItem> Cities { get; set; }

    public RecordViewModel()
    {
        Themes = new List<SelectListItem>();
        Cities = new List<SelectListItem>();
    }
}

контроллер

public async Task<IActionResult> Index()
{
    var lang = "???";
    var model = new RecordViewModel
    {
        Themes = (await repository.GetTableEntitiesAsync<Theme>(lang))
            .Select(x => new SelectListItem {Value = x.Id,Text = x.Text}),
        Cities = (await repository.GetTableEntitiesAsync<City>(lang))
            .Select(x => new SelectListItem { Value = x.Id, Text = x.Text })
    };
    return View(model);
}

public async Task<IActionResult> Edit(string id)
{
    var lang = "???";
    var model = new RecordViewModel
    {
        Id = id,
        Themes = (await repository.GetTableEntitiesAsync<Theme>(lang))
            .Select(x => new SelectListItem { Value = x.Id, Text = x.Text }),
        Cities = (await repository.GetTableEntitiesAsync<City>(lang))
            .Select(x => new SelectListItem { Value = x.Id, Text = x.Text })
    };
    return View(model);
}

другие мысли

Если вы не хотите создавать два вида - один для создания и один для редактирования, вы можете рассмотреть возможность создания частичного представления _CreateOrUpdate.cshtml и поделитесь этим между ними вот так. Вот соответствующие методы Create и Edit.

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

Другие вопросы по тегам