Create a drop-down list for MVC3 using Entity Framework (.edmx Model) and Razor Views && Insert database entry into multiple tables

After reading 100 articles on how to create a DropDown list in MVC 3 using Razor Views, I could not find the one that fits my case. So after hours and hours of searching for an answer, I decided to post this question to find out if anyone has an answer or can help me. Thanks in advance!

Situation: Ultimately, I'm trying to create a view to add an employee to the database.

Here is an image of the .EDMX model I use (the tables that create () will use).:

enter image description here

Tasks:

  • Create an employee (I have Create.cshtml (strongly typed) made with a partial view for StaffNotify flags) {I use a separate @model in the Notify Partial View from Create View, but not sure if this is safe ??? @model ShadowVenue.Models.Employee and @model ShadowVenue.Models.StaffNotify)

  • Create a Dropdown window for StaffTypeId (which will insert the [StaffTypeId] value from the "StaffType" table (with a ratio of 1 to many), but displays the string value [Type] in the drop-down list)

  • Create a drop-down list for GenderId (which will insert the [GenderId] value from the "Genders" table (with a ratio of 1 to many), but will show the value of the [Gender] row in the drop-down list)

  • Insert a record into the database (I have employee notifications in a separate table with a 1 to 1 ratio on the StaffId primary key)

I seem to have problems with the controller code for this.

I'm not sure if I need to create a Stored Procedure in an EDMX model or come up with a query or method syntax, but I'm not sure if this is the best way.

This is my first large MVC3 application using the Entity platform model.

Thank you for your time. I really appreciate the knowledgeable users on this site.

(if you need to know any of the names of the navigation properties to help with the solution, just let me know, I will provide them to you)

+48
asp.net-mvc-3 razor entity-framework edmx html.dropdownlistfor
Mar 16 2018-11-11T00:
source share
2 answers

Do not go db models directly to your views. You are fortunate that you use MVC, so encapsulate it using view models.

Create a view model class as follows:

public class EmployeeAddViewModel { public Employee employee { get; set; } public Dictionary<int, string> staffTypes { get; set; } // really? a 1-to-many for genders public Dictionary<int, string> genderTypes { get; set; } public EmployeeAddViewModel() { } public EmployeeAddViewModel(int id) { employee = someEntityContext.Employees .Where(e => e.ID == id).SingleOrDefault(); // instantiate your dictionaries foreach(var staffType in someEntityContext.StaffTypes) { staffTypes.Add(staffType.ID, staffType.Type); } // repeat similar loop for gender types } } 

Controller:

 [HttpGet] public ActionResult Add() { return View(new EmployeeAddViewModel()); } [HttpPost] public ActionResult Add(EmployeeAddViewModel vm) { if(ModelState.IsValid) { Employee.Add(vm.Employee); return View("Index"); // or wherever you go after successful add } return View(vm); } 

Then, finally, in your view (which you can use Visual Studio to scaffold it first), change the inherited type to ShadowVenue.Models.EmployeeAddViewModel. Also, when the dropdowns go, use:

 @Html.DropDownListFor(model => model.employee.staffTypeID, new SelectList(model.staffTypes, "ID", "Type")) 

and similarly for the gender dropdown

 @Html.DropDownListFor(model => model.employee.genderID, new SelectList(model.genderTypes, "ID", "Gender")) 

Update for comments

For gender, you can also do this if you can be without gender types in the presentation model proposed above (although, on the other hand, perhaps I would generate this server side in the presentation model as IEnumerable). So, instead of new SelectList... below you should use your IEnumerable.

 @Html.DropDownListFor(model => model.employee.genderID, new SelectList(new SelectList() { new { ID = 1, Gender = "Male" }, new { ID = 2, Gender = "Female" } }, "ID", "Gender")) 

Finally, another option is the Lookup table. Basically, you store key-value pairs associated with the type of search. One example of a type may be gender, while the other may be a state, etc. I like to structure mine like this:

 ID | LookupType | LookupKey | LookupValue | LookupDescription | Active 1 | Gender | 1 | Male | male gender | 1 2 | State | 50 | Hawaii | 50th state | 1 3 | Gender | 2 | Female | female gender | 1 4 | State | 49 | Alaska | 49th state | 1 5 | OrderType | 1 | Web | online order | 1 

I like to use these tables when the data set does not change very often, but still needs to be listed from time to time.

Hope this helps!

+75
Mar 16 2018-11-17T00:
source share

Well, actually I will have to say that David is right with his decision, but I am concerned about some topics:

  • You should never send your model to view => That's right
  • If you create a ViewModel and include the Model element as a member in the ViewModel , you actually sent your model to the view =>, this is BAD
  • Using dictionaries to send parameters to the view => this bad style

So how can you create a better connection?

I would use a tool like AutoMapper or ValueInjecter to map between ViewModel and Model. AutoMapper seems to have the best syntax and feels for it, but the current version lacks a very serious topic: it cannot perform a comparison from ViewModel to a model (under certain circumstances, such as flattening, etc., but this is not the topic) Therefore I currently prefer to use ValueInjecter .

So, you create a ViewModel with the fields you need in the view. You add the SelectList elements that you need to search. And you add them as SelectLists already. Thus, you can request data from LINK with sourc support, select the identifier and text field and save it as a list of favorites: you get what you do not need to create a new type (dictionary) as a search, and you just move the new SelectList from submission to the controller.

  // StaffTypes is an IEnumerable<StaffType> from dbContext // viewModel is the viewModel initialized to copy content of Model Employee // viewModel.StaffTypes is of type SelectList viewModel.StaffTypes = new SelectList( StaffTypes.OrderBy( item => item.Name ) "StaffTypeID", "Type", viewModel.StaffTypeID ); 

In the view you just need to call

 @Html.DropDownListFor( model => mode.StaffTypeID, model.StaffTypes ) 

In the post element of your method in the controller, you must take a parameter of type ViewModel . Then you check the confirmation. If the validation fails, you should remember to re-populate the viewModel.StaffTypes SelectList, because this element will be empty when you enter the post function. Therefore, I am inclined to believe that these things of the population are divided into functions. You simply call return new View(viewModel) if something is wrong. Validation errors found by MVC3 will be automatically displayed in the view.

If you have your own verification code, you can add verification errors by indicating to which field they belong. Check the documentation on ModelState for information on this.

If the ViewModel valid, you need to complete the following step:

If this is creating a new element, you need to populate the model from ViewModel ( ValueInjecter is most suitable). You can then add it to this type of EF collection and commit the changes.

If you have an update, you first get the current db element in the model. Then you can copy the values ​​from the ViewModel back to the model (again, using ValueInjecter , you do it very quickly). After that you can SaveChanges and finish.

Feel free to ask, something is unclear.

+23
Mar 16 '11 at 18:29
source share



All Articles