简体   繁体   中英

How to turn a DbSet into a dropdown list, for example?

I'm trying to wrap my head around all of this ViewModel stuff and do things the right way. I have several models linked to SQL tables via Entity Framework, like this one:

[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;}
}

I have a view model like this:

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;}
}

And a bit of my controller like this:

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

So as you can see, in my view, I only need information about one customer/user, but I need to be able to query the entire HardwareOptions, Machines, and PendingOrders tables. Now, if my architecture is entirely wrong, please tell me, because that is more what this question is about. But for something specific, say I want to make a dropdown list from HardwareOptions. Technically, I want each SelectItem to say a string combination of the values of several columns, but for now I'll say I just want one, like Configuration. What is the right way to do that? I don't know how to manipulate the DbSet . When I tried to make a Html.DropDownList from the DbSet , I got a list with the correct number of items, but they all said "mynamespace.Models.HardwareOption." Which makes sense, I just can't figure out how to do it right.

The useful thing you can do with a DbSet<T> in your example is a projection . You would define a second ViewModel that contains the properties you want to show in the dropdown list:

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

Instead of the DbSet you are using a collection of this ViewModel in your OrderIndexViewModel :

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

And only load those properties from the database using a Select method:

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

Edit

You would bind the collection to a dropdown list like so:

@model MyNamespace.OrderIndexViewModel

...

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

Here I have introduced a new property CurrentHardwareOptionId on OrderIndexViewModel that has the same type as the Id ( int in the example) and that is supposed to be the property that the selected Id in the dropdown list is supposed to bind to when the page is posted back:

public class OrderIndexViewModel
{
    //...

    public int CurrentHardwareOptionId { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM