Выбор из имени таблицы, переданного в качестве аргумента в шаблоне репозитория MVC

Я работаю над проектом MVC4, в котором используются шаблоны Unit of Work и Repository. У меня есть около 25 таблиц, которые доступны только для чтения для выпадающего списка или списка множественного выбора. Список может увеличиться в будущем по мере добавления новых модулей. Мне было интересно, могу ли я реализовать общий репозиторий, который возвращает список выбора или множественного выбора в зависимости от имени таблицы (или некоторого псевдонима). Я передаю аргумент функции.

Например.

открытый класс GenericListReopsitory‹'T>, где T — Entity {

общедоступный SelectList GetDropDownList () {

}

публичный MultiSelectList GetMultiSelectList() {

}

}

а затем для доступа в контроллере,

ViewBag.RoleDropDownList = Uow.GenericListObj‹'Role_Master>.GetDropDownList()

Можно ли реализовать что-то подобное в шаблоне репозитория?


person user2755273    schedule 28.09.2013    source источник


Ответы (1)


Через общий репозиторий можно создавать как DropDown, так и MultiSelect списки.

Я уже ответил на свой вопрос о DropDowns, поэтому не буду повторяться.

Список MultiSelect использует тот же метод для пустого списка, но вам нужно что-то еще, если вы хотите редактировать список, отображая текущие выборки (как и в приведенной выше ссылке, я использую chosen.js для отображения поля ввода MultiSelect).

Модели

Существует ViewModel для MultiSelectList, которую я вызываю из основной ViewModel. Проверка проводится в отдельном файле.

MultiSelect ViewModel

public class MultiSelectViewModel
{
    public MultiSelectList Items { get; set; }
}

Entity ViewModel

public partial class InterventionTypeEditViewModel
{
    public int interventionTypeID { get; set; }
    public string interventionType { get; set; }
    public MultiSelectViewModel outcomeID { get; set; }
}

Проверка

[MetadataTypeAttribute(typeof(InterventionTypeEditViewModelMetaData))]
public partial class InterventionTypeEditViewModel
{

}

public class InterventionTypeEditViewModelMetaData
{
    [Key]
    [ScaffoldColumn(false)]
    [HiddenInput(DisplayValue = false)]
    public int interventionTypeID { get; set; }

    [Required]
    [Display(Name = "Intervention Type")]
    public string interventionType { get; set; }

    [Display(Name = "Outcome")]
    [UIHint("_multiEdit")]
    public string outcomeID { get; set; }

}

Шаблон редактора

[UIHint("_multiEdit")] указывает на следующий шаблон редактора. Атрибуты класса предназначены для chosen.js и файла Twitter Bootstrap.

@model WhatWorks.ViewModels.MultiSelectViewModel

@Html.DropDownList("", Model.Items, null, new { @class = "chosen input-xxlarge", multiple = "multiple", })

Контроллер

В контроллере я дважды вызываю репозиторий — один раз для объекта-владельца контроллера (в данном случае tInterventionType) и один раз для объекта, который будет предоставлять наши значения MultiSelectList (tOutcome). Экземпляр _repo относится к параметру универсального типа T в стандартных универсальных методах CRUD, Get и GetById. Экземпляр _multi использует параметр универсального типа O, чтобы различать сущность в репозитории. Это может быть не лучшая практика (советы приветствуются), но это работает.

    private readonly IAdminRepository<tInterventionType> _repo;
    private readonly IAdminRepository<tOutcome> _multi;

    public InterventionTypeController(IAdminRepository<tInterventionType> _repo,
                                        IAdminRepository<tOutcome> _multi)
    {
        this._repo = _repo;
        this._multi = _multi;
    }

Затем в запросе GET для действия Edit selectFrom возвращает все элементы для списка выбора, а currentSelect возвращает уже выбранные элементы. Затем MultiSelectViewModel заполняется с помощью этого MultiSelectList конструктора.< /а>

    // GET: /InterventionType/Edit/5

    public ActionResult Edit(int id = 0)
    {            
        var selectFrom = _multi.Get();
        IEnumerable<int> currentSelect = from o in selectFrom
                            where o.tInterventionType.Any(m => m.interventionTypeID == id)
                            select o.outcomeID;

        MultiSelectViewModel outcome = new MultiSelectViewModel
        {
            Items = new MultiSelectList(selectFrom, "outcomeID", "outcome", currentSelect)
        };

        InterventionTypeEditViewModel a = GetUpdate(id);
        a.outcomeID = outcome;
        if (a == null)
        {
            return HttpNotFound();
        }
        return View(a);
    }

Репозиторий

Метод в репозитории такой же, как стандартный Get(), но параметр универсального типа O относится к передаваемой модели.

    public IEnumerable<O> GetMultiSelectEntity<O>()
                            where O : class
    {
        return context.Set<O>().ToList();
    }

Вид

Как и в случае стандартного DropDown, представление отображает MultiSelectList через Html.Editor, который берет шаблон редактора из аннотации UIHint в файле проверки.


Добавление/редактирование

Чтобы добавить/отредактировать MultiSelect, я использую отдельный универсальный Find в репозитории, чтобы вернуть дочерний объект коллекции. Затем выбранные элементы добавляются в контроллер.

Репозиторий

Верните объект для дочерней коллекции, используя другой общий класс (O).

    public O GetMulti<O>(int id) 
                    where O : class
    {
        return context.Set<O>().Find(id);
    }

Контроллер

Чтобы создать новый экземпляр родительского объекта, Insert родителя, а затем выполните итерацию по коллекции дочерних объектов, добавляя каждый по очереди.

    [HttpPost]
    public ActionResult Create(InterventionTypeAddViewModel model) 
    {
        if (ModelState.IsValid)
        {
            var a = new tInterventionType();
            a.InjectFrom(model);
            _repo.Insert(a);

            foreach (var outcomeId in model.outcome)
            {
                tOutcome o = _repo.GetMulti<tOutcome>(outcomeId);
                a.tOutcome.Add(o as tOutcome);                    
            }

            _repo.Save();
            return RedirectToAction("Index");
        }

        return View(model);
    }

Чтобы отредактировать существующий родительский объект, очистите дочернюю коллекцию и добавьте выбранные элементы в соответствии с методом создания.

    [HttpPost]
    public ActionResult Edit(InterventionTypeUpdateViewModel model, int id)
    {
        if (ModelState.IsValid)
        {
            var a = _repo.GetById(id);
            a.InjectFrom(model);
            a.interventionTypeID = id;
            _repo.Update(a);

            //clear the child collection (outcome on interventionType)
            a.tOutcome.Clear();

            //Add current selection
            foreach (var outcomeId in model.outcomeID)
            {
                tOutcome o = _repo.GetMulti<tOutcome>(outcomeId);
                a.tOutcome.Add(o as tOutcome); 
            }

            _repo.Save();
            return RedirectToAction("Index");
        }
        return View(model);
    }
person melkisadek    schedule 11.07.2014