.net MVC Master Detail View with associated records - asp.net-mvc

I am looking to make a Master Detail View.
I have two tables tbFamily and tbFamilyMember.
I am currently able to view the Family Details and list the associated family members, however, I want to seperate the Family Members based on their Role. i.e. I want to display a list of the Parents/Guardians and then a list of the children ordered by Date of Birth.
My Models are as follows:
public class tbFamily
{
public int tbFamilyID { get; set; }
public string Surname { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string Town { get; set; }
public string County { get; set; }
public string Postcode { get; set; }
public string Country { get; set; }
public string Telephone { get; set; }
public string Mobile { get; set; }
public string Email { get; set; }
public virtual ICollection<tbFamilyMember> tbFamilyMember { get; set; }
public virtual ICollection<tbFamilyData> tbFamilyData { get; set; }
}
public class tbFamilyMember
{
public int tbFamilyMemberID { get; set; }
public int tbFamilyID { get; set; }
public int Role { get; set; }
public string Firstname { get; set; }
public string Surname { get; set; }
public char Gender { get; set; }
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime DateOfBirth { get; set; }
public virtual tbFamily tbFamily { get; set; }
}
My Controller currently looks as follows:
public ActionResult Details(int id = 0)
{
tbFamily tbfamily = db.tbFamily.Find(id);
if (tbfamily == null)
{
return HttpNotFound();
}
return View(tbfamily);
}
Its associated View
#Html.DisplayFor(model => model.Surname)
#Html.DisplayFor(model => model.Address1)
#Html.DisplayFor(model => model.Address2)
#Html.DisplayFor(model => model.Address3)
#Html.DisplayFor(model => model.Town)
#Html.DisplayFor(model => model.County)
#Html.DisplayFor(model => model.Postcode)
#Html.DisplayFor(model => model.Country)
#Html.DisplayFor(model => model.Telephone)
#Html.DisplayFor(model => model.Mobile)
#Html.DisplayFor(model => model.Email)
#foreach (var item in Model.tbFamilyMember)
{
#Html.DisplayFor(modelItem => item.Firstname)
#Html.DisplayFor(modelItem => item.Surname)
#Html.DisplayFor(modelItem => item.Role)
}
To Get the Children:
public ActionResult GetChildren(int id)
{
var tbFamilyData = from f in db.tbFamilyMember
where f.tbFamilyID.Equals(id)
where f.Role.Equals(3)
select f;
return View(tbFamilyData);
}
Its associated View:
#foreach (var item in Model.tbFamilyData)
{
#Html.DisplayFor(modelItem => item.tbFamilyMember.Firstname)
#Html.DisplayFor(modelItem => item.tbFamilyMember.Surname)
#Html.DisplayFor(modelItem => item.tbFamilyMember.Role)
}
Just not sure how to get the two working together!
I have created a seperate Model tbFamilyData
public class tbFamilyData
{
public virtual tbFamily tbFamily { get; set; }
public virtual tbFamilyMember tbFamilyMember { get; set; }
}
I am now getting the error tbFamilyData has no key defined.
Hoping someone can help.

I would suggest one of two options:
1) create viewmodels that better represent your views, and fill them in the controller (my preferred solution).
public class FamilyViewModel
{
public string Surname { get; set; }
... // other props
public ICollection<FamilyMemberViewModel> Parents { get; set; }
public ICollection<FamilyMemberViewModel> Children { get; set; }
}
2) use Linq methods in your view to filter the data to display
<h1>Parents</h1>
#foreach (var item in Model.tbFamilyMember.Where(x => x.Role == Roles.Parent))
{
...
}
<h1>Children</h1>
#foreach (var item in Model.tbFamilyMember.Where(x => x.Role == Roles.Child)
.OrderBy(x => x.DateOfBirth))
{
...
}

Related

CS1061: 'IEnumerable<Orders_Tables>' does not contain a definition for 'labViewResult' and no extension method 'labViewResult'

I got this error when click on details link :
CS1061: 'IEnumerable' does not contain a definition for 'labViewResult' and no extension method 'labViewResult' accepting a first argument of type 'IEnumerable' could be found (are you missing a using directive or an assembly reference?)
This is my model :
public partial class LAB_RESULTS_CLINIC_VIEW
{
public int order_number { get; set; }
public int Test_Id { get; set; }
public string Test_Name { get; set; }
public string Normal { get; set; }
public Nullable<System.DateTime> Report_Date { get; set; }
public string Result { get; set; }
public string Notes { get; set; }
public string Low_Range { get; set; }
public string High_Range { get; set; }
public string Panic { get; set; }
public string Text_Range { get; set; }
public string machine_name { get; set; }
public Nullable<int> Customer_No { get; set; }
public string Customer_Name { get; set; }
public Nullable<int> Patient_No { get; set; }
public string Patient_Name { get; set; }
public string Clinic_File_No { get; set; }
public string Category { get; set; }
public Nullable<int> AGE { get; set; }
public string SEX { get; set; }
public string Test_Note { get; set; }
public string UNIT { get; set; }
public Nullable<int> DEPTID { get; set; }
public Nullable<System.DateTime> Collection_Date { get; set; }
public Nullable<System.DateTime> Receiving_Date { get; set; }
public string Group_Name { get; set; }
public Nullable<int> SERIAL { get; set; }
public int GROUPID { get; set; }
public Nullable<int> packageid { get; set; }
public string EXAMINED_BY { get; set; }
public string APPROVED_BY { get; set; }
public string UPDATED_BY { get; set; }
public Nullable<System.DateTime> UPDATED_DATE { get; set; }
public string Comments { get; set; }
public string department_name { get; set; }
}
}
and i created a tables class orders_tables :
public class Orders_Tables
{
public Lab_Orders LabOrders { get; set; }
public Lab_orders_Cash LabOrdersCash { get; set; }
public Lab_Sample_status LabOrderStatus { get; set; }
public LAB_RESULTS LabResults { get; set; }
public LabTests labtests { get; set; }
public LAB_RESULTS_CLINIC_VIEW labViewResult { get; set; }
public Lab_Hematology_Samples LabSamples { get; set; }
public Patients patients { get; set; }
}
Then this is my controller :
public ActionResult MasterDetails(int id)
{
List<LAB_RESULTS_CLINIC_VIEW> Lab_View = db.LAB_RESULTS_CLINIC_VIEW.ToList();
var OrderResult = from o in Lab_View
where o.order_number == id
select new Orders_Tables { labViewResult = o };
return View(OrderResult);
}
Finally this is my view :
#model IEnumerable<AljawdahNewSite.Models.Orders_Tables>
#{
ViewBag.Title = "MasterDetails";
Layout = "~/Views/Shared/_LayoutPatients.cshtml";
}
<h2>Order Result - نتائج التحاليل </h2>
<div style="margin-left:20px">
<hr/>
<dl class="horizontal">
<dt>#Html.DisplayNameFor(model => model.labViewResult.Patient_Name)</dt>
<dd>#Html.DisplayFor(model => model.labViewResult.Patient_Name)</dd>
<dt>#Html.DisplayNameFor(model => model.labViewResult.Patient_No)</dt>
<dd>#Html.DisplayFor(model => model.labViewResult.Patient_No)</dd>
<dt>#Html.DisplayNameFor(model => model.labViewResult.SEX)</dt>
<dd>#Html.DisplayFor(model => model.labViewResult.SEX)</dd>
<dt>#Html.DisplayNameFor(model => model.labViewResult.AGE)</dt>
<dd>#Html.DisplayFor(model => model.labViewResult.AGE)</dd>
<dt>#Html.DisplayNameFor(model => model.labViewResult.order_number)</dt>
<dd>#Html.DisplayFor(model => model.labViewResult.order_number)</dd>
</dl>
</div>
<div style="align-content:center">
<table class="table table-bordered">
<tr>
<td> test name </td>
<td> result </td>
<td> From Range </td>
<td> To Range </td>
<td> Other Range </td>
<td> Report Date </td>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.labViewResult.Test_Name</td>
<td>#item.labViewResult.Result</td>
<td>#item.labViewResult.Low_Range</td>
<td>#item.labViewResult.High_Range</td>
<td>#item.labViewResult.Text_Range</td>
<td>#item.labViewResult.Report_Date</td>
</tr>
}
</table>
</div>
The error appeared in displatyfor rows
#Html.DisplayFor(model => model.labViewResult.Patient_Name)
How to solve this error , I checked solutions in this site but not solved .
You can solve it by using FirstOrDefault() or First() only but with First() maybe if the order empty will get error "Sequence contains no elements" so the recommended to use FirstOrDefault() :
<dt>#Html.DisplayNameFor(model => model.labViewResult.Patient_Name)</dt>
<dd>#Html.DisplayFor(model => model.FirstOrDefault().labViewResult.Patient_Name)</dd>
<dt>#Html.DisplayNameFor(model => model.labViewResult.Patient_No)</dt>
<dd>#Html.DisplayFor(model => model.FirstOrDefault().labViewResult.Patient_No)</dd>
<dt>#Html.DisplayNameFor(model => model.labViewResult.SEX)</dt>
<dd>#Html.DisplayFor(model => model.FirstOrDefault().labViewResult.SEX)</dd>
<dt>#Html.DisplayNameFor(model => model.labViewResult.AGE)</dt>
<dd>#Html.DisplayFor(model => model.FirstOrDefault().labViewResult.AGE)</dd>
<dt>#Html.DisplayNameFor(model => model.labViewResult.order_number)</dt>
<dd>#Html.DisplayFor(model => model.FirstOrDefault().labViewResult.order_number
And about your question to concatenate dt and dd you can apply some style to dt and dd , you can try the following :
<dt style="width: 30%;display: inline-block;">#Html.DisplayNameFor(model => model.labViewResult.Patient_Name)
</dt><dd style="width: 40%;display: inline-block;">#Html.DisplayFor(model => model.FirstOrDefault().labViewResult.Patient_Name)</dd>

Issue in Display template mvc4

I am new in MVC. I have tried to read online articles about how to use display template in collection.
This is my Model
public class InsuranceListViewModel
{
public IList<InsuranceViewModel> InsuranceViewModelList { get; set; }
public InsuranceViewModel InsuranceViewModel { get; set; }
public List<InsuranceSummaryViewModel> InsuranceSummaryViewModelList { get; set; }
}
SummaryViewModel
public class InsuranceSummaryViewModel
{
public string FriendlyName { get; set; }
public int InsuranceId { get; set; }
public string GroupId { get; set; }
public string MemberId { get; set; }
public Nullable<System.DateTime> PolicyStartDate { get; set; }
public Nullable<System.DateTime> PolicyEndDate { get; set; }
}
InsurnaceDisplay.cshtml
#model P2PExchange.MVC.Web.Areas.Patient.Models.InsuranceSummaryViewModel
#Html.DisplayFor(x => x.InsuranceId)
#Html.DisplayFor(x => x.FriendlyName)
#Html.DisplayFor(x => x.GroupId)
#Html.DisplayFor(x => x.MemberId)
#Html.DisplayFor(x => x.PolicyStartDate)
#Html.DisplayFor(x => x.PolicyEndDate)
_Insurance.cshml
#model Models.InsuranceListViewModel
#Html.DisplayFor(x=>x.InsuranceSummaryViewModelList)
My above code it only displays insurance friendly name not all fields from display template.
Can someone please help/guide me how Can I display correct data on UI?
Your DisplayTemplate needs to be located in the /Views/Shared/DisplayTemplates or /Views/yourControllerName/DisplayTemplates folder and needs to be named to match the name of the class, i.e. InsuranceSummaryViewModel.cshtml

The right way to bind the model to save multiple records to a table

I have a Menusettings pages which displays all the menuname from the database(Menutable).I want to save all the details into MenuRole table.For that I think I have to iterate over each menuitem and store the details in the MenuRole table(Is it the correct method?).But the problem is I am getting MenuList as null.So I couldnot iterate over the menulist .Also I am not sure how can i bind the checkbox value to the MenuRole table.
The view is
Model is
public class MenuRoleVM
{
public int? RoleId { get; set; }
public SelectList RoleList { get; set; }
public MenuRole MenuRole { get; set; }
public IEnumerable<Menu> MenuList { get; set; }
}
public partial class MenuRole
{
public int Id { get; set; }
public Nullable<int> MenuID { get; set; }
public Nullable<int> RoleID { get; set; }
public Nullable<System.DateTime> TransactionTime { get; set; }
public bool CanAdd { get; set; }
public bool CanEdit { get; set; }
public bool CanDelete { get; set; }
public bool CanView { get; set; }
public virtual Menu Menu { get; set; }
public virtual Role Role { get; set; }
}
public partial class Menu
{
public Menu()
{
this.MenuRoles = new HashSet<MenuRole>();
}
public int Id { get; set; }
public string MenuName { get; set; }
public string NavigateUrl { get; set; }
public Nullable<int> ParentID { get; set; }
public virtual ICollection<MenuRole> MenuRoles { get; set; }
}
Controller for binding the View
public ActionResult Add()
{
var _menuRoleVM = new MenuRoleVM
{
RoleList = new SelectList(_db.Roles.ToList(), "Id", "RoleName"),
MenuList = _db.Menus.Where(m => m.NavigateUrl != "#"),
MenuRole = new MenuRole()
};
return View(_menuRoleVM);
}
HTML Markup of View
#model SMS.Models.ViewModel.MenuRoleVM
#foreach (var item in Model.MenuList.Select((x, i) => new { Data = x, Index = i }))
{
<tr>
<td>
<input type="checkbox" class="minimal checkAll" />
</td>
<td>#item.Data.MenuName</td>
<td>
#Html.CheckBoxFor(m => m.MenuRole.CanAdd, new { #class = "minimal single" })
</td>
<td>
#Html.CheckBoxFor(m => m.MenuRole.CanEdit, new { #class = "minimal single" })
</td>
<td>
#Html.CheckBoxFor(m => m.MenuRole.CanDelete, new { #class = "minimal single" })
</td>
<td>
#Html.CheckBoxFor(m => m.MenuRole.CanView, new { #class = "minimal single" })
</td>
</tr>
}
Any help is highly appreciated?
You need view models that represent what you want to display/edit
public class MenuVM
{
public int ID { get; set; }
public string Name { get; set; }
public bool CanAdd { get; set; }
public bool CanEdit { get; set; }
public bool CanDelete { get; set; }
public bool CanView { get; set; }
}
public class MenuRoleVM
{
public int? RoleId { get; set; }
public SelectList RoleList { get; set; }
public List<MenuVM> MenuList { get; set; }
}
and in the view
#model MenuRoleVM
#using (Html.BeginForm())
{
#Html.DropDownListFor(m => m.RoleId, Model.RoleList)
for(int i = 0; i < Model.MenuList.Count; i++)
{
#Html.HiddenFor(m => m.MenuList[i].ID)
#Html.DisplayFor(m => m.MenuList[i].Name)
#Html.CheckBoxFor(m => m.MenuList[i].CanAdd)
#Html.CheckBoxFor(m => m.MenuList[i].CanEdit)
....
}
<input type="submit" ... />
}

[ask]asp.net mvc update database error

I have two model classes in one-to-one relationship:
class Person
{
public int PersonID { get; set; }
public int DetailPersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DetailPerson DetailPerson { get; set; }
}
class DetailPerson
{
public int DetailPersonID { get; set; }
public string Address { get; set; }
public string PhoneNumber { get; set; }
}
and the code for the edit page view:
#using (Html.BeginForm())
{
#Html.HiddenFor(m => m.PersonID)
#Html.LabelFor(m => m.FirstName)
#Html.TextBoxFor(m => m.FirstName)
#Html.LabelFor(m => m.LastName)
#Html.TextBoxFor(m => m.LastName)
#Html.LabelFor(m => m.DetailPerson.Address)
#Html.TextBoxFor(m => m.DetailPerson.Address)
#Html.LabelFor(m => m.DetailPerson.PhoneNumber)
#Html.TextBoxFor(m => m.DetailPerson.PhoneNumber)
<input type="submit" value="Edit">
}
The EF scaffold uses this code to update data:
db.Entry(person).State = System.Data.EntityState.Modified;
db.saveChanges();
When I submit the edit form, I got an error like this:
A foreign key value cannot be inserted because a corresponding primary key value does not exist. [ Foreign key constraint name = FK_dbo.People_dbo.DetailPersons_DetailPersonID ]
But if I do this:
Person p = db.Persons.Find(person.PersonID);
p.DetailPerson = person.DetailPerson;
p.FirstName = person.FirstName;
p.LastName = person.LastName;
db.saveChanges();
update data success without error
I want to know why the first way causse an error,
when I set the breakpoint at the line containing EntityState.Modified,
but the foreign key value ( DetailPersonID ) is 0.
Then, I added #Html.HiddenFor(m => m.DetailPersonID) on the edit form.
I got another error:
A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.
I still update database on the other way,
I am just curious why the first way which is EF standart to update data got an error.
You shouldn't use two classes if there is a one-to-one relationship since EF will normalize the db into the corresponding form anyway. Combine your classes like this.
public class Person
{
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string PhoneNumber { get; set; }
}
if you must have separate classes (not recommended), do it like this:
public class Person
{
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int DetailPersonID { get; set; }
public virtual DetailPerson DetailPerson { get; set; }
}
public class DetailPerson
{
public int PersonID { get; set; }
public virtual Person Person { get; set; }
public int DetailPersonID { get; set; }
public string Address { get; set; }
public string PhoneNumber { get; set; }
}
Then when you retrieve your object, do it like this:
// include the detail when retrieving the parent
Person person = db.People.Include(p=>p.DetailPerson).Single(p=>p.PersonId == whateverIdYou Need);
// modify whatever you like
person.DetailPerson.Address = "my new address";
// then your previous statement will work
db.Entry(person).State = System.Data.EntityState.Modified;
db.saveChanges();

Mapp with automappaer

I have a Model that named word.
this is my word model
public class Word : BaseFieldsTables
{
int ID { get; set; }
string Name { get; set; }
Guid UniqID { get; set; }
DateTime CreatedDate { get; set; }
byte[] RowVersion { set; get; }
public string Text { get; set; }
public virtual Category Category { get; set; }
public int CategoryID { get; set; }
public virtual Language Language { get; set; }
public int LanguageID { get; set; }
public virtual ICollection<Picture> Pictures { get; set; }
[InverseProperty("MainWord")]
public virtual ICollection<RelationshipBetweenWords> MainWords { get; set; }
[InverseProperty("RelatedWord")]
public virtual ICollection<RelationshipBetweenWords> RelatedWords { get; set; }
}
word has a category and language and...
for example this is my language model
public class Language : BaseFieldsTables
{
int ID { get; set; }
string Name { get; set; }
Guid UniqID { get; set; }
DateTime CreatedDate { get; set; }
byte[] RowVersion { set; get; }
public virtual ICollection<Word> Words { get; set; }
}
i have word word viewmodel like this
public class WordViewModel
public string Name { get; set; }
public IList<SelectListItem> Categories { set; get; }
[HiddenInput(DisplayValue = false)]
public int SelectedCategoryID { set; get; }
public IList<SelectListItem> Languages { set; get; }
[HiddenInput(DisplayValue = false)]
public int SelectedLanguageID { set; get; }
}
and this my controller
public ActionResult Index(
{
IList<Word> list = _wordService.GetAll();
}
i want to get all word and map(auotomapper) to my WordViewModel with languagename and category name and return in my view please help me if i have to change my wordviewmodel or... and how to map.tnx
oh i found it
public ActionResult Index()
{
var orders = _respository.GetAll();
AutoMapper.Mapper.CreateMap<Order, OrderDto>()
.ForMember(dest => dest.OrderNumber, opt => opt.MapFrom(src => src.OrderNo))
.ForMember(dest => dest.OrderItemsDto, opt => opt.Ignore());
var model = AutoMapper.Mapper.Map<IEnumerable<Order>, IEnumerable<OrderDto>>(orders);
return View(model);
}
//Razor View Code
<h2>Orders</h2>
<table>
<tr>
<th>Order Number</th>
<th>Name</th>
<th>Total</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.OrderNumber</td>
<td>#item.CustomerName</td>
<td>$#item.Total</td>
</tr>
}
</table>

Resources