例如,如何将DbSet转换为下拉列表?

时间:2012-09-28 20:37:44

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

我正试图绕过所有这些ViewModel的东西并以正确的方式做事。我有几个模型通过Entity Framework链接到SQL表,如下所示:

[Table("HardwareOptions", Schema = "dbo")]
public class HardwareOption {
  [Key]
  public int RecordID {get; set;}
  [ForeignKey("Configuration")]
  public string Configuration {get; set;}
  public string ComputerManufacturer {get; set;}
  public string ComputerModel {get; set;}
  public string ComputerDescription {get; set;}
  public int MonitorCount {get; set;}
  public string MonitorManufacturer {get; set;}
  public string MonitorModel {get; set;}
  public string MonitorDescription {get; set;}
}

我有一个这样的视图模型:

public class OrderIndexViewModel {
  public Customer Customer {get; set;}
  public MetaUser MetaUser {get; set;}
  public DbSet<HardwareOption> HardwareOptions {get; set;}
  public DbSet<Machine> Machines {get; set;}
  public DbSet<PendingOrder> PendingOrders {get; set;}
}

我的控制器有点像这样:

private MyDbContext db = new MyDbContext();
OrderIndexViewModel viewmodel = new OrderIndexViewModel();
viewmodel.Customer = db.Customers.Find("myselffortesting");
viewmodel.MetaUser = db.MetaUsers.Find("myselffortesting");
viewmodel.HardwareOptions = db.HardwareOptions;
viewmodel.Machines = db.Machines;
viewmodel.PendingOrders = db.PendingOrders;
return View(viewmodel);

正如您所看到的,在我看来,我只需要有关一个客户/用户的信息,但我需要能够查询整个HardwareOptions,Machines和PendingOrders表。现在,如果我的架构完全错误,请告诉我,因为这就是这个问题的重点。但是对于特定的事情,我想要从HardwareOptions制作一个下拉列表。从技术上讲,我希望每个SelectItem说出几列值的字符串组合,但是现在我会说我只想要一个,比如Configuration。这样做的正确方法是什么?我不知道如何操纵DbSet。当我尝试从Html.DropDownList创建DbSet时,我得到了一个包含正确数量项的列表,但他们都说“mynamespace.Models.HardwareOption”。这是有道理的,我只是无法弄清楚如何正确地做到这一点。

1 个答案:

答案 0 :(得分:5)

您在示例中使用DbSet<T>可以做的有用的事情是投影。您将定义第二个ViewModel,其中包含您要在下拉列表中显示的属性:

public class HardwareOptionViewModel
{
    public int Id { get; set; }
    public string Configuration { get; set; }
    public string AnotherProperty { get; set; }
    //...
}

而不是DbSet您在OrderIndexViewModel中使用了此ViewModel的集合:

public class OrderIndexViewModel
{
    //...
    public IEnumerable<HardwareOptionViewModel> HardwareOptions { get; set; }
    //...
}

并且只使用Select方法从数据库加载这些属性:

viewmodel.HardwareOptions = db.HardwareOptions
    .Select(h => new HardwareOptionViewModel
    {
        Id = h.Id,
        Configuration = h.Configuration,
        AnotherProperty = h.AnotherProperty,
        //...
    })
    .ToList();

修改

您可以将集合绑定到下拉列表,如下所示:

@model MyNamespace.OrderIndexViewModel

...

<div>
    @Html.DropDownListFor(model => model.CurrentHardwareOptionId,
        new SelectList(Model.HardwareOptions, "Id", "Configuration",
                       Model.CurrentHardwareOptionId))
</div>

这里我在CurrentHardwareOptionId上引入了一个新属性OrderIndexViewModel,它与Id(示例中为int)的类型相同,应该是页面回发时,下拉列表中选定的Id应该绑定的属性:

public class OrderIndexViewModel
{
    //...

    public int CurrentHardwareOptionId { get; set; }
}