Search code examples
c#asp.net-mvcentity-frameworkselectlistviewdata

Putting data from two tables into one ViewData


I'm trying to put data from two tables (AcademicDegrees, Lecturers) connected by one to many relations into one ViewData to generate options to field (with label and id as value). It should be something like this where IDs are used as values and another field as the label.

ViewData["ClassroomsId"] = new SelectList(_context.Classroom, "ClassroomsID", "Number");

When all the data for the field was in one table I used the getter form field to get it.

[NotMapped]
public string toStringVar => FirstName + " " + LastName;

When I added table with academic degrees I moved to a different solution.

var lecturers = _context.Lecturer;
var degree = _context.AcademicDegrees;
var lecturersList = new List<SelectListItem>();

foreach (Lecturers l in lecturers)
{
    _context.AcademicDegrees.Where(d => d.AcademicDegreeId == l.AcademicDegreesId).Load();
    foreach(AcademicDegrees d in degree)
    {
        lecturersList.Add(new SelectListItem(
                  $"{d.Name} {l.FirstName} {l.LastName}", l.LecturersID.ToString()
             ));
        }
    }

ViewData["LecturersId"] = new SelectList(lecturersList);

The problem is that it isn't interpreted as I want it to be.

result

I also can't put it directly into SelectList because it doesn't have an empty constructor or add method. Is there any other way to implement a SelectList?


Solution

  • In my opinion, it is like redundant work as you have the IEnumerable<SelectListItem> instance which can be used to build the select option.

    And you pass IEnumerable<SelectListItem> instance to create the SelectList instance.

    Would suggest to pass IEnumerable<SelectListItem> value to ViewData.

    Solution for IEnumerable<SelectListItem>

    Controller

    ViewData["LecturersId"] = lecturersList;
    

    View

    @Html.DropDownListFor(model => model./*YourProperty*/, (IEnumerable<SelectListItem>)ViewData["LecturersId"])
    

    Updated

    Since you are using ASP.NET Core MVC, with tag helper:

    <select asp-for="/*YourProperty*/" 
        asp-items="@((IEnumerable<SelectListItem>)ViewData["LecturersId"]))">
    </select>
    

    Solution for SelectList

    If you are keen on the SelectList, make sure that you have provided the dataValueField and dataTextField according to this constructor

    public SelectList (System.Collections.IEnumerable items, string dataValueField, string dataTextField);
    

    as below:

    ViewData["LecturersId"] = new SelectList(lecturersList, "Value", "Text");
    

    Besides, the query part would be suggested to optimize by joining both tables as below:

    var lecturersList = (from a in _context.Lecturer
        join b in _context.AcademicDegrees on a.AcademicDegreeId equals b.AcademicDegreeId
        select new SelectListItem($"{b.Name} {a.FirstName} {a.LastName}", a.LecturersID.ToString())
    ).ToList();