Include query result to List - asp.net-mvc

I have a list of Hospitals
Hospital model:
public class Hospital
{
[Key]
public int HospitalID { get; set; }
public string Name { get; set; }
public virtual ICollection<HospitalSpeciality> HospitalSpecialities { get; set; }
public virtual ICollection<UserHospital> UserHospitals { get; set; }
}
and I have users associated to hospital. Model:
public class UserHospital
{
[Key]
public int UserHospitalID { get; set; }
public int HospitalID { get; set; }
public Hospital Hospitals { get; set; }
public string Id { get; set; }
public ApplicationUser Users { get; set; }
}
I need, on my list, return also the number of the user's that are associated to the Hospital.
This query is easy if I have only 1 hospital, but in my scenario, I have a list of hospitals
Controller:
public ActionResult Index()
{
var result = db.Hospitals.ToList();
return View(result);
}
I really don't know how to include the result of the query (number of users) on my list.
My view:
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.HospitalID }) |
#Html.ActionLink("Details", "Details", new { id=item.HospitalID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.HospitalID })
</td>
</tr>
}

It looks like you need to ensure the users are being returned in the query... Like so:
public ActionResult Index()
{
var result = db.Hospitals
.Include("UserHospitals")
.Include("UserHospitals.Users")
.ToList();
return View(result);
}
Even if they are virtual, lazy loading won't occur because you are accessing the property in your razor view. The Include is forcing Eager Loading.
Alternatively, expose another Dbset...
public DbSet<User> Users { get; set; }
Now you can select the following:
db.Users.Where(x => !x.active).ToList();
Let me know how you get on :)

Related

How to Insert checkbox checked values id in Many to Many relationship table?

I wanted to add the value of checkbox ids to many to many relation table between two tables Course-Student
i have 3 tables Course{ CourseID,CourseName }, Studdent{StudentID,StudentName} and CourseStudet{CourseID, StudentID}
Course table already have course{1.DataScience,2.English,3.Physics}
while Inserting Student i have shown course checkboxes with these options fetching list of these courses from database to show in view to user when he is about to register now i am confused how to insert into database?
public class CourseModel {
public List<Course> mycourse{ get; set; }
public string StudentName {get; set;}
}
EF generated Class
public partial class Course
{
public Course()
{
this.Student= new HashSet<Student>();
}
public int CourseID { get; set; }
public string CourseName { get; set; }
i have inserted this field to check for checked value
public bool Ischecked { get; set; }
public virtual ICollection<Student> Student { get; set; }
}
public partial class Student
{
public Student()
{
this.Course= new HashSet<Course>();
}
public int StudentID { get; set; }
public string StudentName { get; set; }
public virtual ICollection<Course> Course{ get; set; }
}
public ActionResult Index()
{
CourseModel coursemodel = new CourseModel();
using (Entities db = new Entities())
{
coursemodel.mycourse = db.Course.ToList<Course>();
return View(coursemodel);
}
}
[HttpPost]
public ActionResult Index(CourseModel course)
{
return View(course);
}
View
#using (Html.BeginForm("index", "Course", FormMethod.Post))
<input type="Text" name="StudentName" placeholder="Name" />
{
<table>
#for (int i = 0 ; i < Model.mycourse.Count; i++)
{
if (i % 3 == 0) {
#:<tr></tr>
}
<div>
#Html.CheckBoxFor(x => x.mycourse[i].Ischecked)
<label>#Model.mycourse[i].CourseName</label>
#Html.HiddenFor(x => x.mycourse[i].CourseID)
#Html.HiddenFor(x => x.mycourse[i].CourseName)
</div>
}
</table>
<input type="submit" value="Submit" />
}
i am getting checkbox id,name and which course is checked now how can i add student with including these values to relationship table CourseStudent ?
You have problems with your database design. Remove ischecked field.Remember while you are designing entities, you shouldn't put fields that are for view. It is like that I make Reports table from my each query.
correct your models
public partial class Course
{
public Course()
{
this.Student = new HashSet<Student>();
}
public int CourseID { get; set; }
public string CourseName { get; set; }
public virtual ICollection<Student> Student { get; set; }
}
public partial class Student
{
public Student()
{
this.Course = new HashSet<Course>();
}
public int StudentID { get; set; }
public string StudentName { get; set; }
public virtual ICollection<Course> Course { get; set; }
}
Add viewmodels(You can use view models for showing custom data for your view)
You can read more
ViewModel
public class CourseViewModel
{
public Course course { get; set; }
public bool CheckBox { get; set; }
}
public class StudentCourseViewModel
{
public List<CourseViewModel> coursesVM { get; set; }
public Student student { get; set; }
}
Controller
public ActionResult index()
{
Entities db = new Entities();
List<CourseViewModel> courselist = new List<CourseViewModel>();
foreach (var item in db.Course.ToList())
{
courselist.Add(new CourseViewModel { course = item});
}
StudentCourceViewModel model = new StudentCourseViewModel(
{
student = new student(),
coursesVM = courselist }
};
return View(model);
}
[HttpPost]
public ActionResult Save(StudentCourseViewModel model)
{
Entities db = new Entities();
Student stdindb = db.Students.FirstorDefault(c => c.StudentName == model.student.StudentName);
if(stdindb == null)
{
stdindb = new student(){//your properties};
db.students.add(stdindb);
}
foreach (var item in model.coursesVM)
{
if (item.Ischecked)
{
stdindb.Course.Add(db.course.single(c=>c.CourseId == item.course.CourseId ));
}
}
db.SaveChanges();
return View();
}
View
#model SchoolCMS.Models.StudentCourseViewModel
#{
ViewBag.Title = "Select Course";
}
#using (Html.BeginForm("Save", "home", FormMethod.Post))
{
#Html.TextBoxFor(c=>c.student.StudentName)
<table>
#for (int i = 0; i < Model.coursesVM.Count; i++)
{
<tr>
<td>
#Html.CheckBoxFor(c => c.coursesVM[i].Ischecked)
#Html.HiddenFor(c => c.coursesVM[i].course.CourseID)
</td>
<td>#Html.DisplayFor(c => c.coursesVM[i].course.CourseName)</td>
</tr>
}
</table>
<input type="submit" value="Submit" />
}

how to pass the count of related model class to view page in asp.net MVC

i have created 2 model classes Mocmodel and mocsubmodel and set navigation property also.for each model id, there will be different submodels for a particular model id. i wanted to create am action link showing count of submodels, when i click on the count, view should display submodel details for each particular modelIDs like below
1220 FXRate count as hyperlink
public class tModel
{
public int ModelID { get; set; }
public string ModelName { get; set; }
public virtual ICollection<tSubModelcs> submodellist { get; set; }
}
public class tSubModelcs
{
public int submodelID { get; set; }
public string submodel { get; set; }
public DateTime launchdate { get; set; }
public int ModelID { get; set; }
}
in my view page i want to display the count of submodel as a link
#foreach (var m in Model)
{
<tr>
<td>#m.ModelID</td>
<td>#m.ModelName</td>
<td>
Html.ActionLink(, "findsubmodels", new { #id = m.ModelID, #class = "linkclick" })
</td>
</tr>
Nothing is clear. Which model are you sending to view ? Post your complete code with action methods. It seems like you are sending IEnumerable of tModel. If this is the case your Actionlink should be like this.
#if(m.submodellist != null)
{
#Html.ActionLink(m.submodellist.Count.ToString(), "findsubmodels",null, new { id = #m.ModelID, #class = "linkclick" })
}
Replace the null with your routevalue if any.

Self-referencing model MVC 4

I have a component that have a list of subcomponents:
public class Componente
{
public virtual int ComponentId { get; set; }
public virtual string NameComp { get; set; }
public virtual List<Subcomponent> Subcomponents { get; set; }
}
public class Subcomponent
{
public virtual int SubcomponentId { get; set; }
public virtual int ParentId { get; set; }
public virtual string NameSub { get; set; }
public virtual Component CompSub { get; set; }
public virtual List<Subcomponent> Children { get; set; }
}
Then i have a view that shows the components, their subcomponents and in the future the subsubcomponents and so on.
<table>
...
if (item.Subcomponents.Count != 0)
{
foreach (var x in item.Subcomponents)
{
<tr>
<td>
#Html.DisplayFor(modelItem => x.NameSub)
</td>
<td>
#Html.ActionLink("Create Subcomponent", "CreateMoreSubcomponents", "Subcomponent", new { id = x.SubcomponentId }, null)
</td>
</tr>
}
}
}
</table>
And the create method:
public ActionResult CreateMoreSubcomponents(int id)
{
var x = db.Subcomponents.FirstOrDefault(e => e.SubcomponentId == id);
if (x == null)
{
return HttpNotFound();
}
var subcomponent = new Subcomponent()
{
ParentId = x.SubcomponentId
};
return View("CreateMoreSubcomponents", subcomponent);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateMoreSubcomponents(Subcomponent subcomponent)
{
if (ModelState.IsValid)
{
db.Subcomponents.Add(subcomponent);
db.SaveChanges();
...
}
The goal is to have subsubcomponents, subsubsubcomponents and so on. But the code that i show here is not working, it gives an error in the db.SaveChanges(); because it asks for the componentId but i don't know what do i have to change. What do i need to change or do? Thanks

The model item passed into the dictionary is of type List, but this dictionary requires a model item of type IEnumerable

I'm facing an exception below :
The model item passed into the dictionary is of type 'System.Collections.Generic.List1[DropDownList.Models.Department]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[DropDownList.Models.Employee]'.
Here is my model,
Employee.cs :
public class Employee
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public int DepartmentId { get; set; }
public virtual Department Department { get; set; }
}
Department.cs :
public class Department
{
public int DepartmentId { get; set; }
public string DeptCode { get; set; }
public string DepartmentName { get; set;}
public string Syscode { get; set; }
public virtual ICollection<Employee> Employees { get; set; }
}
and my EmployeesController's index action, where the exception generates :
public ActionResult Index()
{
var employees =
from dept in db.Departments
select new
{
dept,
depts = from emp in dept.Employees
where dept.Syscode == "isols123"
select dept
};
var employs = employees
.AsEnumerable()
.Select(m => m.dept);
return View(employs.ToList());
}
and here is my index view :
#model IEnumerable<DropDownList.Models.Employee>
.
.
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Department.DepartmentName)
</td>
<td>
#Html.DisplayFor(modelItem => item.EmployeeName)
</td>
</tr>
}
What is going wrong, I've no idea, I'm seriously stuck on this one :(, anyone please take me out of this, Thanks in Advance..
Essentially, the code:
public ActionResult Index()
{
var employees =
from dept in db.Departments // This makes dept of type Department
select new
{
dept,
depts = from emp in dept.Employees
where dept.Syscode == "isols123"
select dept
};
var employs = employees
.AsEnumerable()
.Select(m => m.dept); // Selects Department
return View(employs.ToList());
}
Returns a list of Departments (even tho the variables are called employs) and your view expects it to be a list of Employees.
Both these should match for it to work.
Assuming the linq queries are right, this will make it expect a List of Departments on the view:
#model List<DropDownList.Models.Department>

MVC: best way to display data from 2 tables in 1 view

I'm trying to make a view that has data from 2 tables in my database. I have looked up a couple things and I tried to use a ViewModel but I can't get it to work. Then I was thinking about using a view and a partial view to display data from the 2 tables. What is the best way using the ViewModel or using a view and a partial view?
Also if someone knows what I am doing wrong with my ViewModel and wants to help that would be awesome.
my 2 models:
public partial class prospect
{
public prospect()
{
this.result = new HashSet<result>();
}
public int id { get; set; }
public int testid { get; set; }
public string name { get; set; }
public string surname { get; set; }
public string email { get; set; }
public string cellnumber { get; set; }
public System.DateTime timestampstart { get; set; }
public Nullable<System.DateTime> timestampend { get; set; }
public Nullable<int> totalresult { get; set; }
public string birthdate { get; set; }
public string school { get; set; }
public Nullable<int> grade { get; set; }
public string address { get; set; }
public string cityandcode { get; set; }
public virtual ICollection<result> result { get; set; }
public virtual resultpersection resultpersection { get; set; }
}
public partial class resultpersection
{
public int id { get; set; }
public int prospectid { get; set; }
public int sectionid { get; set; }
public Nullable<int> result { get; set; }
public virtual prospect prospect { get; set; }
public virtual section section { get; set; }
}
The things I want to display are:
prospect.name , prospect.surname, prospect.totalresult and all the results per section of this prospect(this comes from the resultpersection table)
my viewmodel:
namespace testAptitude.Models
{
public class ResultsPerProspect
{
public List<prospect> prospect { get; set; }
public List<resultpersection> resultPerSection { get; set; }
}
}
my controller
public ActionResult Index()
{
ResultsPerProspect vm = new ResultsPerProspect();
vm.prospect = (from p in db.prospect select p).ToList();
vm.resultPerSection = (from rps in db.resultpersection select rps).ToList(); ;
List<ResultsPerProspect> viewModelList = new List<ResultsPerProspect>();
viewModelList.Add(vm);
return View(viewModelList.AsEnumerable());
}
my view
#model IEnumerable<testAptitude.Models.ResultsPerProspect>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<table>
<thead>
<tr>
<th class="col-sm-3">
#Html.DisplayNameFor(model => model.prospect)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(model => item.prospect)
</td>
</tr>
}
</tbody>
</table>
I can't do item.prospect.name because it say's that is doesn't contain a definition for name
and what is dispalys now is this:
prospect
System.Collections.Generic.HashSet`1[testAptitude.Models.result]
Thanks in advance!
With your current code you can access it using
#Html.DisplayNameFor(model => model.FirstOrDefault().prospect)
You are passing IEnumerable<testAptitude.Models.ResultsPerProspect> to your view i.e multiple objects of class ResultsPerProspect. You would need to iterate throught this List. Each items in this list will contain definition for prospect and resultPerSection.
Or you can pass single object of class ResultsPerProspect as you are just adding single element in list.
UPDATE
You have List Of ResultsPerProspect. and each item of ResultsPerProspect has List of prospect and List of resultPerSection. So you would need to first iterate for loop over List Of ResultsPerProspect. and inside that for loop , for loop for List of prospect List of and resultPerSection
CODE
#foreach (var item in Model)
{
foreach (var pros in item.prospect)
{
<tr>
<td>
#Html.DisplayFor(model => pros.Name)
</td>
</tr>
}
}
Why don't you create a class ("Container") that consists of your two (sub)classes (let's say A and B)? You can then create a Container object and put the needed objects in Container.A and Container.B. You can then easly pass "Container" to your view and access your objects.

Resources