最简洁的方法是使用复合值从数据库填充MVC下拉列表?

时间:2018-01-19 00:36:25

标签: c# asp.net-mvc entity-framework html.dropdownlistfor

我需要从数据库填充下拉列表,我正在寻找最简洁的方法。

我已经开始工作了:

viewModel.CrewList = db.Crew.AsNoTracking().Select(x => new 
SelectListItem
{
    Value = x.CrewID,
    Text = x.FirstName + " " + x.LastName
}).ToList();

我觉得它有点冗长,我真的不喜欢SelectListItems的列表。

通常我会尝试这样的事情:

viewModel.CrewList = new SelectList(db.Crew.ToList(), "CrewId", "Name");

但是,当我尝试使用复合值时,它会出错:

viewModel.CrewList = new SelectList(db.Crew.ToList(), "CrewId", "FirstName + ' ' + LastName");

这个也会在下拉列表中产生奇怪的结果(对于anon对象和SelectListItems):

viewModel.CrewList = new SelectList(db.CREW_EVW.Select(c => new 
{ Value = c.CrewID, Text = c.FirstName + " " + c.LastName })
.ToList());

将来,最好的方法是什么?

1 个答案:

答案 0 :(得分:2)

  
    

将来,最好的方法是什么?

  
viewModel.CrewList = db.Crew.AsNoTracking().Select(x => new 
SelectListItem
{
    Value = x.CrewID,
    Text = x.FirstName + " " + x.LastName
}).ToList();

但严重的是,关键是你不要加载整个表来填充列表,你的其他两个方法都通过调用db.Crew.ToList();

如果要避免使用SelectListItems,可以将匿名类型的集合传递给SelectList。 EG

new SelectList(db.Crew.Select( c => new {c.CrewId, Name=c.FirstName + " " + x.LastName}).ToList());

哪个很容易重构为

db.Crew.Select( c => new {c.CrewId, Name=c.FirstName + " " + x.LastName} ).ToSelectList();

db.Crew.ToSelectList( c => new {c.CrewId, Name=c.FirstName + " " + x.LastName} );

使用简单的扩展方法,例如

public static SelectList ToSelectList<T,W>(this DbSet<T> dbSet, Expression<Func<T,W>> selector) where T:class
{
    return new SelectList(dbSet.AsNoTracking().Select(selector).AsEnumerable());
}

或异步

public static async Task<SelectList> ToSelectListAsync<T, W>(this DbSet<T> dbSet, Expression<Func<T, W>> selector) where T : class
{
    var results = await dbSet.AsNoTracking().Select(selector).ToListAsync();
    return new SelectList(results);
}