创建一个通用的List <selectlistitem>函数

时间:2019-03-20 13:53:39

标签: c# asp.net-core-mvc asp.net-core-2.2

我有两个DbSet:

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

在控制器中,我正在创建两个List<SelectListItem>

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 个答案:

答案 0 :(得分:2)

也许您可以让dbset继承基类。这将代表通用类型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);

请注意-未测试

答案 1 :(得分:2)

我的解决方案使用不同的方法,但结果相同。

从界面开始:

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