【问题标题】:Create a generic List<SelectListItem> function创建一个通用 List<SelectListItem> 函数
【发布时间】:2019-03-20 13:53:38
【问题描述】:

我有两个 DbSet:

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

在控制器中,我创建了两个List&lt;SelectListItem&gt;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.&lt;T&gt; 部分的正确方法是什么?也许这应该是DbSet 的扩展方法?

【问题讨论】:

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


    【解决方案1】:

    也许您可以让您的数据库集继承一个基类。这将表示泛型类型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);
    

    请注意 - 未经测试

    【讨论】:

      【解决方案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();
      

      【讨论】:

      • 我喜欢这种方法。扩展方法是否支持布尔值以包含“选择值”选项?
      • 当然,您可以添加一个 bool 参数(请参阅我的编辑)。或者,您可以根据需要添加 SelectListItem 参数。甚至是 List 参数,如果你想有多个额外的项目
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-05
      相关资源
      最近更新 更多