Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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,

like image 293
russds Avatar asked Dec 21 '22 16:12

russds


1 Answers

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

like image 193
Brendan Vogt Avatar answered Jan 08 '23 10:01

Brendan Vogt