How to use foreign key relationship in mvc4 - c#

I have School, Teachers and Qualifications tables in my database. Teacher table refs qualificationid and schoolid in Qualification and Schools table.
I'm not using Entity Framework and I have DB-connection class to do CLUED operations.
In my Teacher class
public int TeacherID { get; set; }
public string Name { get; set; }
public string NIC { get; set; }
public string Address { get; set; }
public int Telephone { get; set; }
public Nullable<int> SchoolID { get; set; }
public Nullable<int> QualificationID { get; set; }
public virtual Qualifications Qualifications { get; set; }
public virtual Schools Schools { get; set; }
My schools class
public int SchoolID { get; set; }
public string Name { get; set; }
public int Telephone { get; set; }
public string Address { get; set; }
public virtual ICollection<Teachers> Teachers { get; set; }
My Qualification class
public int QualificationID { get; set; }
public string Type { get; set; }
public virtual ICollection<Teachers> Teachers { get; set; }
My DBConnection class
public List<Teachers> getAllTeachers()
{
List<Teachers> teachersdata=new List<Teachers>();
string connection = Connection.ConnectionString;
SqlConnection con = new SqlConnection(connection);
con.Open();
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = "Select * from Teachers as T,Qualifications as Q,Schools as S where S.SchoolID=T.SchoolID and T.QualificationID=Q.QualificationID";
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.KeyInfo);
while(dr.Read())
{
Teachers teacher = new Teachers();
teacher.TeacherID = dr.GetInt32(0);
teacher.Name = dr.GetString(1);
teacher.NIC = dr.GetString(2);
teacher.Address = dr.GetString(3);
teacher.Telephone = dr.GetInt32(4);
teacher.SchoolID = dr.GetInt32(5);
teacher.QualificationID = dr.GetInt32(6);
teacher.Qualifications.QualificationID = (Int32)dr["QualificationID"];
teacher.Qualifications.Type =(string) dr["Type"];
teacher.Schools.SchoolID = (Int32)dr["SchoolID"];
teacher.Schools.Name = (string)dr["Name"];
teacher.Schools.Telephone = (Int32)dr["Telephone"];
teacher.Schools.Address = (string)dr["Address"];
teachersdata.Add(teacher);
}
return teachersdata;
}
in teachersController
public ActionResult Index()
{
List<Teachers> allTeachers = _db.getAllTeachers();
return View(allTeachers);
}
at last in index.aspx i have
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<IEnumerable<MyLayer.Teachers>>" %>
<!DOCTYPE html>
<html>
<head runat="server">
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<p>
<%: Html.ActionLink("Create New", "Create") %>
</p>
<table>
<tr>
<th>
<%: Html.DisplayNameFor(model => model.TeacherID) %>
</th>
<th>
<%: Html.DisplayNameFor(model => model.Name) %>
</th>
<th>
<%: Html.DisplayNameFor(model => model.NIC) %>
</th>
<th>
<%: Html.DisplayNameFor(model => model.Address) %>
</th>
<th>
<%: Html.DisplayNameFor(model => model.Telephone) %>
</th>
<th>
<%: Html.DisplayNameFor(model => model.Schools.Name) %>
</th>
<th>
<%: Html.DisplayNameFor(model => model.Qualifications.Type) %>
</th>
<th></th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td>
<%: Html.DisplayFor(modelItem => item.TeacherID) %>
</td>
<td>
<%: Html.DisplayFor(modelItem => item.Name) %>
</td>
<td>
<%: Html.DisplayFor(modelItem => item.NIC) %>
</td>
<td>
<%: Html.DisplayFor(modelItem => item.Address) %>
</td>
<td>
<%: Html.DisplayFor(modelItem => item.Telephone) %>
</td>
<td>
<%: Html.DisplayFor(modelItem => item.Schools.Name) %>
</td>
<td>
<%: Html.DisplayFor(modelItem => item.Qualifications.Type) %>
</td>
<td>
<%: Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) %> |
<%: Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) %> |
<%: Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ }) %>
</td>
</tr>
<% } %>
</table>
</body>
</html>
But when I run the project i got this error Object reference not set to an instance of an object in dbconnnection class teacher.Qualifications.QualificationID = (Int32)dr["QualificationID"]; .how can i fix this?

I did a LINQPad program with this code
void Main()
{
Teachers teacher = new Teachers();
teacher.TeacherID = 12;
teacher.Name = "Jones";
teacher.Qualifications.QualificationID = 7;
teacher.Dump();
}
This is similar to the part you have in your loop. The problem is that teacher.Qualifications expects an instance of an object. But you did not create one. In your line teacher.Qualifications.QualificationID you are trying to assign a value to the non-static property QualificationID.
You could write
var qual = new Qualifications();
qual.QualificationID = 7;
teacher.Qualifications = qual;
Please let me know if you need more help.

Related

Pass ID from view of type IEnumerable using HTML Actionlink in Razor

I have two models "Computer" and "Computer Detail." From the Computer's Index page the user can click "View Details" for a given record which redirects to the Index of the Computer Detail and fetches all the records associated with that given "Computer ID" using the query string - That works fine
My problem is I want to have a "Create" link that carries this "Computer ID" (shown in view) and populates the Computer ID field on the Create form.
I used Model.First().ComputerID that worked to run the code with some test records but of course it doesn't work if records for the ComputerID is null.
View
#modelIEnumerable<MyApp.Models.ComputerDetail>
#{
ViewBag.Title = "Index";
}
<h2 class ="page-header">Computer Details</h2>
<div class ="col-lg-12">
<p>
#Html.ActionLink("Create New", "Create", "ComputerDetail", new {id = Model.First().ComputerID}, new { #class = "btn btn-default"})
</p>
<div class="panel panel-default">
<div class ="panel-body">
<table class ="table table-striped" id="dtaTable">
<thead class ="dataTableHead">
<tr>
<th>
#Html.DisplayNameFor(model => model.ComputerID)
</th>
<th>
#Html.DisplayNameFor(model => model.EmployeeID)
</th>
<th>
#Html.DisplayNameFor(model => model.StartDate)
</th>
<th>
#Html.DisplayNameFor(model => model.EndDate)
</th>
<th>
#Html.DisplayNameFor(model => model.Comments)
</th>
<th>Actions</th>
</tr>
</thead>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ComputerID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Employee.FullName)
</td>
<td>
#Html.DisplayFor(modelItem => item.StartDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.EndDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.Comments)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
#Html.ActionLink("Details", "Details", new { id=item.ID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
</div>
</div>
</div>
Controller
public ActionResult Index(int id)
{
var _FindComputerID = GetComputerDetails(id);
return View(_FindComputerID);
}
private List<ComputerDetail>GetComputerDetails(int id)
{
var FindComputerID = db.ComputerDetails.Where(cd => cd.ComputerID == id).Include
(cd => cd.Employee).OrderByDescending(cd => cd.ID);
return FindComputerID.ToList();
}
[HttpGet]
public ActionResult Create(int id)
{
ComputerDetail computerdetail = new ComputerDetail ();
computerdetail.ComputerID = id;
return View(computerdetail);
}
Model
public class ComputerDetail
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required(ErrorMessage = "Please enter service tag")]
[Display(Name = "Service Tag")]
public int ComputerID { get; set; }
[Required(ErrorMessage = "Please select employee name")]
[Display(Name = "Employee Name")]
public int EmployeeID { get; set; }
[Required(ErrorMessage = "Please enter date")]
[Display(Name = "Date Bought")]
[DataType(DataType.Date)]
public DateTime StartDate { get; set; }
[Display(Name = "Date Bought")]
[DataType(DataType.Date)]
public DateTime? EndDate { get; set; }
public string Comments { get; set; }
//references
public virtual Assets.Computer Computer { get; set; }
public virtual Employee Employee { get; set; }
}
Two thing are happening here:
In the first place, if your view needs to get the ComputerID you may want to reflect this field in the ViewModel and not magically get it from the first item in the list.
public class ComputerDetailsViewModel
{
public int ComputerID {get; set;} // populate in the action directly
public IEnumerable<MyApp.Models.ComputerDetail> Items {get; set;}
}
You really want to go that route, you should use the nullable operator for better error handling figure it out what happens when the ComputerID is null.
#Html.ActionLink("Create New", "Create", "ComputerDetail", new {id = Model.FirstOrDefault()?.ComputerID ?? 0 /*Null case*/}, new { #class = "btn btn-default"})
Hope this help!

C# , MVC , Instead table html

I have this model :
public class CoursesTeacher
{
public int Id { get; set; }
public string FullName { get; set; }
public IEnumerable<string> CourseName { get; set; }
public IEnumerable<int> CourseId { get; set; }
}
I would like to create an Instead table html by razor.
The teacher has a multiple courses.
like that
that
I wrote this code :
<table class="table table-bordered">
<tr>
<th>
#Html.ActionLink("Teacher Name", "RequestsTeachers")
</th>
<th>
#Html.ActionLink("Corese Name", "RequestsTeachers")
</th>
<th>
Edit
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td rowspan="#item.CourseName.Count()">
#Html.DisplayFor(modelItem => item.FullName)
</td>
#foreach (var courseName in item.CourseName)
{
<td>
#Html.DisplayFor(modelItem => courseName)
</td>
}
#foreach (var courseId in item.CourseId)
{
<td>
<div class="pull-right">
#Html.NoEncodeActionLink("<span class='glyphicon glyphicon-pencil'></span>", "Edit", "EditFinancial", "Control", routeValues: new { courseId = courseId }, htmlAttributes: new { data_modal = "", #class = "btn btn-default" })
</div>
</td>
}
</tr>
}
but created not correct :
correct
how to create correct ?
I'd go and create a viewmodel to represent the info for a course:
public class CourseInfoModel
{
public string CourseName { get; set; }
public int CourseId { get; set; }
public bool IsFirstCourse { get; set; }
}
Then in the model class, create a readonly property to get the data in a more suitable way:
public class CoursesTeacher
{
public int Id { get; set; }
public string FullName { get; set; }
public IEnumerable<string> CourseName { get; set; }
public IEnumerable<int> CourseId { get; set; }
public IList<CourseInfoModel> Courses
{
get
{
if (CourseName == null || CourseId == null || CourseId.Count() != CourseName.Count())
throw new Exception("Invalid data"); //courses and ids must have the same number of elements
var list = new List<CourseInfoModel>();
for (int i = 0; i < CourseName.Count(); i++)
{
list.Add(new CourseInfoModel
{
IsFirstCourse = i == 0,
CourseId = CourseId.ElementAt(i),
CourseName = CourseName.ElementAt(i),
});
}
return list;
}
}
}
Now in the view is easy to render the table the way you want:
#model IEnumerable<MvcTable.Models.CoursesTeacher>
<table class="table table-bordered">
<tr>
<th>
#Html.ActionLink("Teacher Name", "RequestsTeachers")
</th>
<th>
#Html.ActionLink("Course Name", "RequestsTeachers")
</th>
<th>
Edit
</th>
</tr>
#foreach (var item in Model)
{
foreach (var courseItem in item.Courses)
{
<tr>
#if (courseItem.IsFirstCourse)
{
<td rowspan="#item.Courses.Count">
#Html.DisplayFor(modelItem => item.FullName)
</td>
}
<td>
#Html.DisplayFor(modelItem => courseItem.CourseName)
</td>
<td>
<div class="pull-right">
<span class='glyphicon glyphicon-pencil'></span>
</div>
</td>
</tr>
}
}
</table>
Instead of keeping the CourseName and CourseIds to seperate lists. Why not create a class to represent a course and use that ?
public class CourseVm
{
public int Id { set; get;}
public string Name { set; get;}
}
public class CoursesTeacher
{
public int Id { set;get;}
public string FullName { set;get;}
public List<CourseVm> Courses { set;get;}
}
and in the view which is strongly typed to a collection CoursesTeacher
#model IEnumerable<CoursesTeacher>`
<table>
#foreach(var t in Model)
{
<tr>
<td>#t.FullName</td>
<td>
<table>
#foreach(var c in t.Courses)
{
<tr><td>#c.Name</td>
<td><button>Some button</button></td>
</tr>
}
</table>
</td>
</tr>
}
</table>

How to pass textbox value from strongly typed view(#model List<viewmodel>) to controller

view
#model List<PMS.View_Model._ContributeViewModel>
#{
ViewBag.Title = "Contribute";
}
#using (Html.BeginForm())
{
#Html.Partial("_Project")
#Html.ValidationSummary(true)
<table>
<tr>
<th>
<u>Current Members</u>
</th>
</tr>
<tr>
<th>
ProjectID
</th>
<th>
Name
</th>
<th>
Role
</th>
</tr>
#foreach(var item in Model.Where(m=>m.Status==1))
{
<tr>
<td>
#Html.DisplayFor(model=>item.ProjectID)
</td>
<td>
#Html.DisplayFor(model=>item.Name)
</td>
<td>
#Html.DisplayFor(model=>item.RoleName)
</td>
</tr>
}
<tr>
<th>
<u>Invited Members</u>
</th>
</tr>
<tr>
<th>
ProjectID
</th>
<th>
Name
</th>
</tr>
#foreach(var item2 in Model.Where(m=>m.Status==0))
{
<tr>
<td>
#Html.DisplayFor(model=>item2.ProjectID)
</td>
<td>
#Html.DisplayFor(model=>item2.Name)
</td>
</tr>
}
<tr>
<td>
#Html.TextBoxFor(?)
</td>
<td>
<input type="submit" id="btnsearch" value="Search"/>
</td>
</tr>
</table>
}
viewmodel
public class _ContributeViewModel
{
public int UserID { get; set; }
[StringLength(20)]
public string Name { get; set; }
[StringLength(20)]
public string Email { get; set; }
[StringLength(20)]
public string Facebook { get; set; }
[StringLength(20)]
public string Twitter { get; set; }
[StringLength(20)]
public string LinkedIn { get; set; }
[StringLength(20)]
public string Github { get; set; }
[StringLength(50)]
public string Password { get; set; }
[StringLength(50)]
public string Photo { get; set; }
[StringLength(100)]
public string Address { get; set; }
[StringLength(50)]
public string PhoneNo { get; set; }
[StringLength(500)]
public string Other { get; set; }
public DateTime CreateDate { get; set; }
public int RoleID { get; set; }
public int ProjectID { get; set; }
[StringLength(20)]
public string RoleName { get; set; }
public int Status { get; set; }
}
Controller
[HttpGet]
public ActionResult Contribute(int? projectID)
{
PMSDBContext PMP = new PMSDBContext();
//List<_ContributeViewModel> cvm = new List<_ContributeViewModel>();
// _Contribute cv=new _Contribute();
// cvm = cv.GetMember();
List<_ContributeViewModel> result = new List<_ContributeViewModel>();
result = PMP.Relations
.Join(PMP.Roles, a => a.RoleID,
b => b.RoleID,
(a, b) => new { Relation = a, Role = b })
.Join(PMP.Users,
a => a.Relation.UserID,
c => c.UserID,
(a, c) => new { a.Relation, a.Role, Users = c })
.Where(a => a.Relation.ProjectID == 1)
.Select(a => new _ContributeViewModel
{
ProjectID = a.Relation.ProjectID,
RoleName = a.Role.RoleName,
Name = a.Users.Name,
Status = a.Relation.Status,
}
).ToList();
return View(result);
}
[HttpPost]
public ActionResult Contribute(_ContributeViewModel Model)
{
return View();
}
Problem i am facing is that..i cant use #Html.TextBoxFor(m=>Model.Name or Something) to pass textbox value to controller..it is because of List?but if i remove List<>..i get problems in foreach loop...Should i use partial view for this textbox? or is there any better ways than using partial views?Please Suggest...
You can use TextBox() this way:
#{
int index = 0;
}
#foreach(var item2 in Model.Where(m=>m.Status==0))
{
#Html.TextBox("Model["+index.ToString()+"].ProjectID",item2.ProjectID)
#Html.TextBox("Model["+index.ToString()+"].Name",item2.Name)
#{ index = index +1; }
}
You may also refer to this article
Simply create one new Model class, like:
public class _ContributeViewModel2
{
List<PMS.View_Model._ContributeViewModel> ContributeList { get; set; }
string SearchString { get; set; }
}
Pass this to your View and use like this,
#model _ContributeViewModel2
#{
ViewBag.Title = "Contribute";
}
#using (Html.BeginForm())
{
#Html.Partial("_Project")
#Html.ValidationSummary(true)
<table>
<tr>
<th>
<u>Current Members</u>
</th>
</tr>
<tr>
<th>
ProjectID
</th>
<th>
Name
</th>
<th>
Role
</th>
</tr>
#foreach(var item in Model.ContributeList.Where(m=>m.Status==1))
{
<tr>
<td>
#Html.DisplayFor(item.ProjectID)
</td>
<td>
#Html.DisplayFor(item.Name)
</td>
<td>
#Html.DisplayFor(item.RoleName)
</td>
</tr>
}
<tr>
<th>
<u>Invited Members</u>
</th>
</tr>
<tr>
<th>
ProjectID
</th>
<th>
Name
</th>
</tr>
#foreach(var item2 in Model.ContributeList.Where(m=>m.Status==0))
{
<tr>
<td>
#Html.DisplayFor(item2.ProjectID)
</td>
<td>
#Html.DisplayFor(item2.Name)
</td>
</tr>
}
<tr>
<td>
#Html.TextBoxFor(model=> m.SearchString)
</td>
<td>
<input type="submit" id="btnsearch" value="Search"/>
</td>
</tr>
</table>
}
Thank you.

Using multiple tables in Index View in MVC

I know that If I want to see data from just one table in my Index View, I have to do this:
public class LocalidadesController : Controller
{
// GET: /Localidades/
private Entities db = new Entities();
//
// GET: /Concessao/
[Authorize(Roles = "ADMINISTRADOR")]
public ActionResult Index()
{
return View(db.SINCO_LOCALIDADE_CONCESSAO.ToList());
}
For two tables (in my case, views), I'm doing the changes below (localidades_view and municipios_view are the
views that I want to select data).
Model:
namespace SINCO_MVC.Models
{
[MetadataType(typeof(SincoLocalidadeConcessaoMetaData))]
public partial class SINCO_LOCALIDADE_CONCESSAO
{
}
public class SincoLocalidadeConcessaoMetaData
{
[Display(Name = "ID LOCALIDADE:")]
public int[] IDLOCALIDADE { get; set; }
[Display(Name = "ID:")]
public int IDCONCESSAO { get; set; }
[Display(Name = "Localidade:")]
public virtual LOCALIDADES_VIEW LOCALIDADES_VIEW { get; set; }
public virtual MUNICIPIOS_VIEW MUNICIPIOS_VIEW { get; set; }
}
}
View:
<%# Page Title="SINCO - Localidades" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<SINCO_MVC.Models.SINCO_LOCALIDADE_CONCESSAO>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
SINCO - Localidades
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>SINCO - Localidades</h2>
<table>
<tr>
<th>
<%: Html.DisplayNameFor(model => model.IDCONCESSAO) %>
</th>
<th>
<%: Html.DisplayNameFor(model => model.IDLOCALIDADE) %>
</th>
<th></th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td>
<%: Html.DisplayFor(modelItem => item.MUNICIPIOS_VIEW.NOME_MUNICIPIO) %>
</td>
<td>
<%: Html.DisplayFor(modelItem => item.LOCALIDADES_VIEW.NOME_LOCALIDADE) %>
</td>
I did something like this, but it didn't work, because this fields in index stays empty.
How can I access the data of this views(oracle views)??
*Sorry for my bad english.
Make a ViewModel which contains two fields, one for each table, Done...something like
public class MyViewModel
{
public MyType Table1 {get;set;}
public MyType2 Table2 {get;set;}
}
The problem it was because of LazyLoad. I added the tables in my model but because of LazyLoad nothing returned. I had to add this code below in my index:
[Authorize(Roles = "ADMINISTRADOR")]
public ActionResult Index(SINCO_LOCALIDADE_CONCESSAO model)
{
return View("Index", db.SINCO_LOCALIDADE_CONCESSAO.Include(s => s.LOCALIDADES_VIEW).Include(s => s.MUNICIPIOS_VIEW));
}
Now it's working fine!

NullReferenceException: Object reference not set to an instance of an object. in a foreach loop

I'm having trouble with the instance of my object it gave me an error in which i don't understand
List<Event> events = parseResponse.Deserialize<List<Event>>(_responseAsString);
ViewBag.eventss = events;
html
<table id="eventist" border="0" cellspacing="0" cellpadding="0">
<thead>
<tr>
<th>
event_key
</th>
<th>
user_token
</th>
<th>
event_set_key
</th>
<th>
event_type
</th>
<th>
event_date
</th>
<th>
event_amount
</th>
<th>
event_location_key
</th>
<th>
event_location_name
</th>
<th>
event_location_city
</th>
<th>
event_location_state
</th>
<th>
event_location_country
</th>
<th>
event_acknowledged
</th>
</tr>
</thead>
<tbody>
<%List<StopMalaria.Models.Event> events= ViewBag.eventss;%>
<% foreach (var item in events)
{ %>
<tr>
<td>
<%: item.event_key%>
</td>
<td>
<%: item.user_token%>
</td>
<td>
<%: item.event_set_key%>
</td>
<td>
<%: item.event_type%>
</td>
<td>
<%: item.event_date%>
</td>
<td>
<%: item.event_amount%>
</td>
<td>
<%: item.event_location_key%>
</td>
<td>
<%: item.event_location_name%>
</td>
<td>
<%: item.event_location_city%>
</td>
<td>
<%: item.event_location_state%>
</td>
<td>
<%: item.event_location_country%>
</td>
<td>
<%: item.event_acknowledged%>
</td>
</tr>
<% } %>
</tbody>
</table>
So i did this. now it is saying [NullReferenceException: Object reference not set to an instance of an object.] and my <% foreach(var item in events) are highlighted red .
I already have a class with all of the element
public class Event
{
public string event_key { get; set; }
public string user_token { get; set; }
public string event_set_key { get; set; }
public string event_type { get; set; }
public string event_date { get; set; }
public string event_amount { get; set; }
public string event_location_key { get; set; }
public string event_location_name { get; set; }
public string event_location_city { get; set; }
public string event_location_state { get; set; }
public string event_location_country { get; set; }
public string event_acknowledged { get; set; }
}
Add a viewmodel for your view, sample may look like. Also use this viewmodel in your action:
public class EventListModel
{
public EventListModel()
{
EventList = new List<Event>();
}
public string FormId { get; set; }
public string ProgramId { get; set; }
public string FormName { get; set; }
public IList<Event> EventList { get; set; }
}

Categories

Resources