Search code examples
c#asp.netasp.net-mvcentity-frameworklinq

Sending data with viewbag


I am working on a project. I need to get several data from database and send to view. I have already a list of data. And I also want to send my another datas via viewbag. I queried my related data from database.

ClassController.cs

public ActionResult ClassTeacherDetail(int id)
        {

            ViewBag.dgr = db.Teachers.Where(m => m.Id == id).FirstOrDefault();


            var myList = (from t in db.Appointments
                     from d in t.WeekDays
                     where t.TeacherId == id
                     select new { DayName=d.Name, WHours=t.Hours }
                ).ToList();


            // Get the languages which can be learned by the teacher based on teacher id
            var query = from t in db.Teachers.Where(x => x.Id == id)
                        from l in t.Languages
                        select new
                        {
                            LangName = l.Name,
                        };
            var list = new List<Language>();
            foreach (var item in query)
            {
                list.Add(new Language()
                {
                    Name = item.LangName
                });
            }

            return View(list);
        }

enter image description here

As you see, I got the working hours and days from separate tables. By the way, what is the type of myList? If I would send it to view, what will the model type be?

How can I pass the myList?


Solution

  • myList is a List of type Anonymous object, there's nothing wrong with that but it will be hard to keep track of. What we need to do is make a class/model for it THEN make a viewmodel that will contain both variables.

    1. Make a model or view model for myList anonymous object, I used TeacherAppointment;
    // if the property/data type doesn't match with your Appointments model, please change accordingly
    public class TeacherAppointment {
       public string DayName {get;set;}
       public string WHours {get;set;}
    }
    
    1. Update myList LINQ to store it to a TeacherAppointment object. myList is now List<TeacherAppointment>
    var myList = (from t in db.Appointments
                    from d in t.WeekDays
                    where t.TeacherId == id
                    select new TeacherAppointment { DayName=d.Name, WHours=t.Hours }
                  ).ToList();
    
    1. Create a view model that will contain 2 models.
    public class TeacherDetailViewModel{
       public List<TeacherAppointment> TeacherAppointments {get;set;}
       public List<Language> Languages {get;set;}
    }
    
    1. In your view, you should use;
    @model TeacherDetailViewModel
    
    1. Your controller code should be;
    public ActionResult ClassTeacherDetail(int id)
            {
    
                ViewBag.dgr = db.Teachers.Where(m => m.Id == id).FirstOrDefault();
    
    
                var myList = (from t in db.Appointments
                         from d in t.WeekDays
                         where t.TeacherId == id
                         select new TeacherAppointment { DayName=d.Name, WHours=t.Hours }
                    ).ToList();
    
    
                // Get the languages which can be learned by the teacher based on teacher id
                var query = from t in db.Teachers.Where(x => x.Id == id)
                            from l in t.Languages
                            select new
                            {
                                LangName = l.Name,
                            };
                var list = new List<Language>();
                foreach (var item in query)
                {
                    list.Add(new Language()
                    {
                        Name = item.LangName
                    });
                }
    
                // instantiate view model
                TeacherDetailViewModel tdvm = new TeacherDetailViewModel();
    
                // assign myList and list to TeacherDetailViewModel
                tdvm.TeacherAppointments = myList;
                tdvm.Languages = list;
    
                // Pass tdvm to the view
                return View(tdvm);
            }
    
    1. In your view again, if you want to loop;
    @foreach(var a in Model.TeacherAppointments){
       ...
    }
    
    @foreach(var b in Model.Languages){
       ...
    }