Создать универсальную функцию List <SelectListItem> - PullRequest
0 голосов
/ 20 марта 2019

У меня есть два DbSets:

public DbSet<Reports.Models.Application> Application { get; set; }
public DbSet<Reports.Models.Category> Category { get; set; }

В контроллере я создаю два List<SelectListItem> s:

var applications = _context.Application
    .Select(listItem => new SelectListItem 
      { 
        Value = listItem.ID, 
        Text = listItem.Name 
      }
    ).ToList();

var categories = _context.Category
    .Select(listItem => new SelectListItem
      {
        Value = listItem.ID, 
        Text = listItem.Name
      }
    ).ToList();

Я хотел бы преобразовать это в один частный метод:

private List<SelectListItem> SelectList<T>(bool blankListItem = false)
{
    var selectListItems = _context.<T>  <------ doesn't compile
        .Select(listItem => new SelectListItem
          {
            Value = listItem.ID,
            Text = listItem.Name
          }
        ).ToList();

    if (blankListItem) 
        selectListItems.Insert(0, (new SelectListItem { Text = $"Choose {{T.ToString}}", Value = "" }));

    return selectListItems;
}

И позвоните дважды:

var applications = SelectList<Application>(); 
var categories = SelectList<Category>();

или

var applications = SelectList<Application>(true); // add "choose" 
var categories = SelectList<Category>(true); // add "choose"

Как правильно определить деталь _context.<T>? Возможно, это должен быть метод расширения DbSet вместо этого?

Ответы [ 2 ]

2 голосов
/ 20 марта 2019

Мое решение использует другой подход, но тот же результат.

Начните с интерфейса:

public interface IBaseSelectItem
{
    int Id { get; set; }
    string Name { get; set; }
}

Ваши объекты (приложение и категория) реализуют интерфейс:

public partial class Category : IBaseSelectItem
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Создайте расширение на DbSet:

public static IList<SelectListItem> AsSelectList<T>(this DbSet<T> dbSet, bool useChooseValueOption) where T : class, IBaseSelectItem
{
    var selectList = dbSet
        .Select(c => new SelectListItem { Value = c.Id.ToString(), Text = c.Name })
        .ToList();

    if (useChooseValueOption)
        selectList.Insert(0, new SelectListItem { Value = "0", Text = "-Choose Value-" });

    return selectList;
}

Затем используйте вот так:

var categoriesSelectList = _dbContext.Categories.AsSelectList();
2 голосов
/ 20 марта 2019

Возможно, вы можете сделать так, чтобы ваши dbsets наследовали базовый класс. который будет представлять общий тип T.

Нечто подобное;

public class BaseClassForDbSets
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Application : BaseClassForDbSets
{
}

public class Category : BaseClassForDbSets
{
}

а затем ваш личный метод;

private IEnumerable<SelectListItem> GetSelectList<T>(IEnumerable<T> dataSource, bool blankListItem = false) where T : BaseClassForDbSets
    {
        var selectListItems = dataSource 
              .Select(listItem => new SelectListItem
              {
                  Value = listItem.Id.ToString(),
                  Text = listItem.Name
              }
              ).ToList();

        if (blankListItem)
            selectListItems.Insert(0, (new SelectListItem { Text = $"Choose {nameof(T)}", Value = "" }));

        return selectListItems;
    }

Тогда вы бы назвали это как;

var applicationCollection = GetSelectList(_context.Application);
var categoryCollection = GetSelectList(_context.Category);

Обратите внимание - не проверено

...