asp.net-mvc-3foreign-key-relationship

Using a foreign key in dropdown in mvc


I'm new to MVC, and stuck on what should be a pretty straight forward issue. I'm working through this tutorial and got everything pretty much working, except I now want to add a foreign key 'link' (not sure what it's called) but can't seem to get it to work. Here's what I have:

Tables:

 Inventory:
 Id   |  SerialNumber  | ManufacturerId (foreignkey to Manufactueres->id)

 Manufactureres
 Id (primary key)   |  Name

Model (InventoryItem.cs):

 public class InventoryItem {
     public int Id {get; set; }
     public int SerialNumber{ get; set; }

     //this starts the trouble, I actually want to interact with the Manufactureres table -> Name column
     public int ManufacturerId { get; set; }  
 }

View (Create.cshtml):

 ...
 //What i really want is a dropdown of the values in the Manufactureres table
 @Html.EditorFor(model=> model.ManufacturerId)

This must be a farely common issue when using a relational database there would be many foreign key relationships to be used/shown, but for some reason i can't find a tutorial or issue on stackoverflow that directly corresponds to something so simple. Any guidance, or direction is much appreciated! Thanks,


Solution

  • I hope I understand your question correctly. Seems like when you want to add a new inventory item then you want a list of all the manufacturers in a dropdown list. I am going to work on this assumption, please let me know if I am off the track :)

    Firstly go and create a view model. This view model you will bind to yout view. Never bind domain objects to your view.

    public class InventoryItemViewModel
    {
         public int SerialNumber { get; set; }
    
         public int ManufacturerId { get; set; }
    
         public IEnumerable<Manufacturer> Manufacturers { get; set; }
    }
    

    Your domain objects:

    public class InventoryItem
    {
         public int Id { get; set; }
    
         public int SerialNumber{ get; set; }
    
         public int ManufacturerId { get; set; }
    }
    
    public class Manufacturer
    {
         public int Id { get; set; }
    
         public string Name { get; set; }
    }
    

    Your controller might look like this:

    public class InventoryItemController : Controller
    {
         private readonly IManufacturerRepository manufacturerRepository;
         private readonly IInventoryItemRepository inventoryItemRepository;
    
         public InventoryItem(IManufacturerRepository manufacturerRepository, IManufacturerRepository manufacturerRepository)
         {
              // Check that manufacturerRepository and inventoryItem are not null
    
              this.manufacturerRepository = manufacturerRepository;
              this.inventoryItemRepository = inventoryItemRepository;
         }
    
         public ActionResult Create()
         {
              InventoryItemViewModel viewModel = new InventoryItemViewModel
              {
                   Manufacturers = manufacturerRepository.GetAll()
              };
    
              return View(viewModel);
         }
    
         [HttpPost]
         public ActionResult Create(InventoryItemViewModel viewModel)
         {
              // Check that viewModel is not null
    
              if (!ModelState.IsValid)
              {
                   Manufacturers = manufacturerRepository.GetAll()
    
                   return View(viewModel);
              }
    
              // All validation is cool
    
              // Use a mapping tool like AutoMapper
              // to map between view model and domain model
              InventoryItem inventoryItem = Mapper.Map<InventoryItem>(viewModel);
    
              inventoryItemRepository.Insert(inventoryItem);
    
              // Return to which ever view you need to display
              return View("List");
         }
    }
    

    And then in your view you might have the following:

    @model MyProject.DomainModel.ViewModels.InventoryItems.InventoryItemViewModel
    
    <table>
         <tr>
              <td class="edit-label">Serial Number <span class="required">**</span></td>
              <td>@Html.TextBoxFor(x => x.SerialNumber, new { maxlength = "10" })
                  @Html.ValidationMessageFor(x => x.SerialNumber)
              </td>
         </tr>
         <tr>
              <td class="edit-label">Manufacturer <span class="required">**</span></td>
              <td>
                   @Html.DropDownListFor(
                        x => x.ManufacturerId,
                        new SelectList(Model.Manufacturers, "Id", "Name", Model.ManufacturerId),
                        "-- Select --"
                   )
                   @Html.ValidationMessageFor(x => x.ManufacturerId)
              </td>
         </tr>
    </table>
    

    I hope this helps :)