how i update multiple table using viewmodel in Asp.net mvc - c#

Employee Model
public class Employee
{
[Key]
public int EmployeeID { get; set; }
public string Name { get; set; }
public virtual Department Departments { get; set; }
public int DepartmentID { get; set; }
}
Department Model
public class Department
{
public int DepartmentID { get; set; }
public string DepartmentName { get; set; }
}
View Model for Department and Employee
public class EDViewModel
{
public int ID { get; set; }
public int EmployeeID { get; set; }
public string Name { get; set; }
public Department Departments { get; set; }
public int DepartmentID { get; set; }
public string DepartmentName { get; set; }
}
Now i want to update both tables with single view.
Controller
public ActionResult Edit(int?id)
{
// write some code for update both table at once time
}
PostMethod
[HttpPost]
public ActionResult Edit(EDViewModel Emodel)
{
var user = db.Employees.Where(c => c.Employee_Id == Emodel.Employee_Id).FirstOrDefault();
user.UserName = Emodel.UserName;
user.ProfilePicture = Emodel.ProfilePicture;
db.Entry(user).State = EntityState.Modified;
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Home");
}
But in this method only Update Employee record not department

After many searching finally i get a solid solution
hope you like or improve this.
Controller
public ActionResult Edit(int? id)
{
MYDb db = new MYDb();
var user = db.Employees.Where(c => c.Employee_Id == Emodel.Employee_Id).FirstOrDefault();
if (user != null)
{
var vm = new EDViewModel { Employee_id = user.Employee_id, departmentName = user.departmentName };
if (user.department != null)
{
user.Departmet_id = vm.Departments.Departmet_id;
user.DepartmentName = vm.Departments.DepartmentName;
user.Employee_id = vm.employee_id;
user.employeeName = vm.employeeName;
}
return View(user);
}
return Content("Invalid Id");
}
[HttpPost]
public ActionResult Edit(EDViewModel Emodel)
{
var user = db.Employees.Where(c => c.Employee_Id == Emodel.Employee_Id).FirstOrDefault();
user.EmployeeId = Emodel.EmployeeId;
user.EmployeeName= Emodel.EmployeeName;
user.DepartmentName= Emodel.Departmt.DepartmentName;
// Just remove this line
// db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Home");
}

it worked for me
just remove this
db.Entry(user).State = EntityState.Modified;
if we not remove this entityvalidation occur

Related

Entity Framework MVC Code First BIND doesn't work for children entities inside EDIT action

I am using ASP Core Web Application, MVC, Code First, with MySQL db.
Here is the structure of my db:
Here is code for those 2 models/classes:
=====This code is for 2nd EmployeeDate Table (Child)=====
[Table("employeedate")]
{
[Key]
[Required]
[Column("ID", TypeName = "int(10)")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required]
[Column("HiredDate", TypeName = "date")]
public DateTime HiredDate { get; set; }
[Column("FiredDate", TypeName = "date")]
public DateTime? FiredDate { get; set; }
[Required]
//[Timestamp]
[Column("ModifiedDate", TypeName = "datetime")]
public DateTime ModifiedDate { get; set; }
[Required]
[Column("EmployeeID", TypeName = "int(10)")]
public int EmployeeID { get; set; }
// This attribute specifies which database field is the foreign key.
[ForeignKey(nameof(EmployeeID))]
// InverseProperty links the two virtual properties together.
[InverseProperty(nameof(Models.Employee.EmployeeDates))]
public virtual Employee Employee { get; set; }
}
=====This code is for 1st Employee Table (Parent) =====
[Table("employee")]
public class Employee
{
public Employee()
{
EmployeeDates = new HashSet<EmployeeDate>();
}
public string GetHiredDate
{
get
{
var hiredate = "this employee has never been hired";
if (EmployeeDates.LastOrDefault() != null)
{
hiredate = EmployeeDates.LastOrDefault().HiredDate.ToLongDateString();
}
return hiredate;
}
}
public string GetFiredDate
{
get
{
var firedate = "active";
if (EmployeeDates.LastOrDefault() != null && EmployeeDates.LastOrDefault().FiredDate.HasValue)
{
firedate = EmployeeDates.LastOrDefault().FiredDate.Value.ToLongDateString();
}
return firedate;
}
}
private DateTime hireddate = DateTime.Now;
public DateTime HiredDate
{
get
{
return hireddate;
}
}
public DateTime? FiredDate
{
get
{
DateTime? fireddate = null;
if (EmployeeDates.LastOrDefault() != null && EmployeeDates.LastOrDefault().FiredDate.HasValue)
{
fireddate = EmployeeDates.LastOrDefault().FiredDate.Value;
}
return fireddate;
}
}
[Key]
[Required]
[Column("ID", TypeName = "int(10)")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required]
[Column("FirstName", TypeName = "varchar(60)")]
public string FirstName { get; set; }
[Required]
[Column("LastName", TypeName = "varchar(60)")]
public string LastName { get; set; }
[Required]
[Column("Email", TypeName = "varchar(100)")]
public string Email { get; set; }
[Required]
[Column("Phone", TypeName = "varchar(20)")]
public string Phone { get; set; }
[Required]
[Range (16, 100)]
[Column("Age", TypeName = "int(1)")]
public int Age { get; set; }
[Required]
[Column("City", TypeName = "varchar(100)")]
public string City { get; set; }
[Required]
[Column("Department", TypeName = "varchar(100)")]
public string Department { get; set; }
[InverseProperty(nameof(Models.EmployeeDate.Employee))]
public virtual ICollection<EmployeeDate> EmployeeDates { get; set; }
}
CREATE method works fine including HiredDate (Not FiredDate). But EDIT works only for Employee properties , FiredDate property is not working. I can update everything else like First name, Age, etc but not FiredDate.
Here is code inside Controller:
// GET: Employee/Create
public IActionResult Create(int ID =0)
{
return View(new Employee());
}
// POST: Employee/Create
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(string firstName, string lastName, string email, string phone, int age, string city, string department, DateTime HiredDate)
{
//Nov20 add 2 objects and append HireDate separately from another Table
var employee = new Employee { FirstName = firstName, LastName = lastName, Email = email, Phone = phone, Age = age, City = city, Department = department };
var employeeDate = new EmployeeDate { HiredDate = HiredDate };
employee.EmployeeDates.Add(employeeDate);
if (ModelState.IsValid)
{
_context.Add(employee);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(employee);
}
// GET: Employee/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var employee = await _context.Employees.FindAsync(id);
if (employee == null)
{
return NotFound();
}
return View(employee);
}
// POST: Employee/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,FirstName,LastName,Email,Phone,Age,City,Department,FiredDate")] Employee employee)
{
if (id != employee.ID)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(employee);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!EmployeeExists(employee.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(employee);
}
And finally Views:
====Edit====
====Create====
Btw when comment out FiredDate div inside Create View(because its not needed there) my project fails to build right away.
Any suggestions on what am i doing wrong? I'm new to this ASP Code First approach.
Here are some more pics:

How to make user to Like/Dislike picture only for once in .Net Core

I want to make that a user can only give a like or a dislike only once per picture. I made an additional model
public class Marking
{
public int IdMema { get; set; }
public string Authorr {get;set;}
public int Like { get; set; }
public int Dislike { get; set; }
}
and this in Memy model
public partial class Memy
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[HiddenInput]
public int Id_mema { get; set; }
public string Autor { get; set; }
[Required]
public string Title { get; set; }
[HiddenInput]
public string coverImg { get; set; }
public string Description { get; set; }
public string Category { get; set; }
[HiddenInput]
public DateTime? releaseDate { get; set; }
public DateTime? modifyDate { get; set; }
public int? Like { get; set; }
public int? Dislike { get; set; }
}
Here is the method in MemyController
public async Task<IActionResult> Like(int id, Marking user)
{
System.Security.Claims.ClaimsPrincipal currentUser = this.User;
var memy = db.Memy.SingleOrDefault(s => s.Id_mema == id);
memy.Like++;
List<Marking> ee = new List<Marking>();
if (id != memy.Id_mema)
{
return NotFound();
}
foreach (var z in ee)
{
if (ModelState.IsValid && z.Authorr == currentUser.Identity.Name && z.IdMema == id && z.Like == 0)
{
z.Like = 1;
db.Update(memy);
await db.SaveChangesAsync();
}
return RedirectToAction("Show", new { id = id });
}
return RedirectToAction("Show", new { id = id });
}
I don't know why this is not working .
I put a breakpoint here :
if (ModelState.IsValid && z.Authorr == currentUser.Identity.Name && z.IdMema == id && z.Like == 0)
and the program didn't check the if, why?
I changed my method in MemyController
public async Task<IActionResult> Like(int id)
{
var memy = db.Memy.SingleOrDefault(s => s.Id_mema == id);
var marking = db.Marking.SingleOrDefault(s => s.IdMema == id);
memy.Like++;
if (id != memy.Id_mema)
{
return NotFound();
}
System.Security.Claims.ClaimsPrincipal currentUser = this.User;
if (ModelState.IsValid && marking.IdMema==id && marking.Authorr==currentUser.Identity.Name && marking.CountLike==0)
{
db.Update(memy);
await db.SaveChangesAsync();
return RedirectToAction("Show", new { id = id });
}
return RedirectToAction("Show", new { id = id });
}
``
and I add-migration and update-database ,but every time I receive answer that datebase do not contain Marking
Thanks for help :)

Nested entity not being saved

I have the following method that saves an EmailTemplate. Based on the ID of a dropdown it populates the EmailAccount as the foreign entity property.
public ActionResult Edit([Bind(Include = "EmailAccountId, EmailTemplate")] EmailTemplateViewModel emailTemplateViewModel)
{
if (ModelState.IsValid)
{
if (emailTemplateViewModel.EmailAccountId > 0)
{
emailTemplateViewModel.EmailTemplate.EmailAccount = db.EmailAccounts.Find(emailTemplateViewModel.EmailAccountId);
}
db.Entry(emailTemplateViewModel.EmailTemplate).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(emailTemplateViewModel);
}
Everything in the EmailTemplate saves fine apart from EmailAccount. In debugger I can see that the property is populated before db.SaveChanges() is called.
I am setting the entity state to EntityState.Modified but it's not picking up the foreign property.
I tried adding:
db.Entry(emailTemplateViewModel.EmailTemplate.EmailAccount).State = EntityState.Modified;
But this didn't work. How do I tell EntityFramework that it needs to save the nested entity?
Edit:
As requested
public class EmailTemplateViewModel
{
public List<EmailAccount> EmailAccounts { get; set; }
public EmailTemplate EmailTemplate { get; set; }
[Display(Name = "Email Account")]
public int EmailAccountId { get; set; }
public IEnumerable<SelectListItem> EmailAccountsList
{
get
{
var allEmails = EmailAccounts.Select(e => new SelectListItem { Value = e.ID.ToString(), Text = e.Email });
return DefaultEmailAccountList.Concat(allEmails);
}
}
public IEnumerable<SelectListItem> DefaultEmailAccountList
{
get
{
return Enumerable.Repeat(new SelectListItem
{
Value = "-1",
Text = "Select Email Account"
}, count: 1);
}
}
}
public class EmailTemplate
{
public int ID { get; set; }
[StringLength(50)]
[Index(IsUnique = true)]
public string Identifier { get; set; }
public int Interval { get; set; }
public string TitleTemplate { get; set; }
[DataType(DataType.MultilineText)]
public string BodyTemplate { get; set; }
public virtual EmailAccount EmailAccount { get; set; }
}
I was modifying before I attached so the change wasn't tracked.
This works
if (ModelState.IsValid)
{
db.Entry(emailTemplateViewModel.EmailTemplate).State = EntityState.Modified;
if (emailTemplateViewModel.EmailAccountId > 0)
{
emailTemplateViewModel.EmailTemplate.EmailAccount = db.EmailAccounts.Find(emailTemplateViewModel.EmailAccountId);
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(emailTemplateViewModel);

Many to Many Relationship on MVC5

So I'm in the middle of a project where I need to have a Many-to-Many relationship between Teams and Members.
One team can have many users (from aspnetusers) and a user can have 0 or more teams.
But at the moment, One team can have many users, but one user can only have 1 team, whenever I try to add a user on a new team, that user is removed from team he's already in.
I've reached this point thanks to http://cpratt.co/associating-related-items-in-a-collection-via-a-listbox/
My Team Model:
public class EquipaModel
{
[Key]
public int EquipaID { get; set; }
[Required]
[Display (Name="Nome")]
public string EquipaNome { get; set; }
[Required]
[Display (Name="Descrição")]
public string EquipaDescricao { get; set; }
[Display(Name = "Team Manager")]
public string TeamManagerId { get; set; }
public virtual ApplicationUser TeamManager { get; set; }
public virtual ICollection<ApplicationUser> Membros { get; set; }
}
My extended user model
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity>
GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager
.CreateIdentityAsync(this,
DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
public virtual Utilizador Utilizador { get; set; }
}
[Table("Utilizadores")]
public class Utilizador
{
public int Id { get; set; }
public string PrimeiroNome { get; set; }
public string Apelido { get; set; }
public int Pontuacao { get; set; }
public int PaisID { get; set; }
public virtual PaisModel Pais { get; set; }
//public IEnumerable<LinguasProgModel> Linguagens { get; set; }
}
My Team ViewModel
public class EquipasViewModel
{
[Required]
public string EquipaNome { get; set; }
public string EquipaDescricao { get; set; }
public string TeamManagerId { get; set; }
public virtual ApplicationUser TeamManager { get; set; }
[Required]
public List<string> MembrosID { get; set; }
public IEnumerable<SelectListItem> MembrosEscolhidos { get; set; }
}
My Create on EquipaController (TeamController)
public ActionResult Create()
{
ViewBag.TeamManagerId = new SelectList(db.Users, "Id", "Email");
var model = new EquipasViewModel();
PopulateMembrosEscolhidos(model);
return View(model);
}
[HttpPost]
public ActionResult Create(EquipasViewModel model)
{
if (ModelState.IsValid)
{
var equipa = new EquipaModel
{
EquipaNome = model.EquipaNome,
EquipaDescricao = model.EquipaDescricao,
TeamManagerId = model.TeamManagerId,
Membros = db.Users.Where(m => model.MembrosID.Contains(m.Id)).ToList()
};
db.Equipas.Add(equipa);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.TeamManagerId = new SelectList(db.Users, "Id", "Email", model.TeamManagerId);
PopulateMembrosEscolhidos(model);
return View(model);
}
and finally the Edit on my team controller
public ActionResult Edit(string id)
{
ViewBag.TeamManagerId = new SelectList(db.Users, "Id", "Email");
var equipa = db.Equipas.FirstOrDefault(e => e.EquipaNome == id);
if (equipa == null)
{
return new HttpNotFoundResult();
}
var model = new EquipasViewModel
{
EquipaNome = equipa.EquipaNome,
EquipaDescricao = equipa.EquipaDescricao,
MembrosID = equipa.Membros.Select(m => m.Id).ToList()
};
PopulateMembrosEscolhidos(model);
return View(model);
}
[HttpPost]
public ActionResult Edit(string id, EquipasViewModel model)
{
var equipa = db.Equipas.FirstOrDefault(e => e.EquipaNome == id);
if (equipa == null)
{
return new HttpNotFoundResult();
}
if (ModelState.IsValid)
{
equipa.EquipaNome = model.EquipaNome;
equipa.EquipaDescricao = model.EquipaDescricao;
equipa.Membros.Where(m => !model.MembrosID.Contains(m.Id))
.ToList()
.ForEach(m => equipa.Membros.Remove(m));
var MembrosNaEquipa = equipa.Membros.Select(m => m.Id);
var NovosMembros = model.MembrosID.Except(MembrosNaEquipa);
db.Users.Where(m => NovosMembros.Contains(m.Id))
.ToList()
.ForEach(m => equipa.Membros.Add(m));
db.Entry(equipa).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
PopulateMembrosEscolhidos(model);
return View(model);
}
At some point, I'm going to remove the selectlist and replace it for a textbox where the user inputs user names to add to the memberlist of the team - but at the moment i'm just trying to figure out how to save the many-to-many relationship.
Edit
I had that feeling that it was something simple, but just couldn't get there. I started using that solution, but came across an error that to be honest, I've never seen before.
Multiplicity constraint violated. The role 'ApplicationUser_Equipas_Source' of the relationship 'Codings.Models.ApplicationUser_Equipas' has multiplicity 1 or 0..1.
It happens on line "db.Equipas.Add(equipa);" of Create.
It's probably my mistake, since I tried to add a team to the users simply by
var MembrosEscolhidos = db.Users.Where(m => model.MembrosID.Contains(m.Id)).ToList();
foreach (var item in MembrosEscolhidos)
{
item.Equipas.Add(equipa);
}
I think one easy fix would be to reference your EquipaModel as a collection in your users table.
e.g.
public virtual ICollection<EquipaModel> Equipas { get; set; }
like you reference your users in your EquipaModel
e.g.
public class EquipaModel
{
...
public virtual ICollection<ApplicationUser> Membros { get; set; }
}
Then your users can have many "Equipas" or teams.

Editing/Listing multiple models within one view

I am new to the MVC and EF world. I am targeting MVC 4 EF 5 using code first.
I am looking for the best practice for editing two related models using one view. For simplicity I have the following two Models:
namespace AddressBook.Models
{
public class Contact
{
public int ID { get; set; }
public string First_Name { get; set; }
public string Last_Name { get; set; }
public List<PhoneNumber> PhoneNumbers { get; set; }
}
}
and
namespace AddressBook.Models
{
public class PhoneNumber
{
public int ID { get; set; }
public string Number { get; set; }
public bool Primary { get; set; }
}
}
with the following context:
using System.Data.Entity;
namespace AddressBook.Models
{
public class DataContext : DbContext
{
public DbSet<Contact> Contacts { get; set; }
public DbSet<PhoneNumber> PhoneNumbers { get; set; }
}
}
The relationship between the Contact and PhoneNumber is one to many, However I would like to be able to edit the first_name, last_name and Number when the Primary is set to true, so we would be editing only one phone number per contact record.
I have seen similar posts that point to using a ViewModel but the only examples of viewmodels I have seen are when used instead of the viewbag when passing the information for a dropdown.
I guess I have a few questions:
would the ViewModel look like below?
public class ContactPrimaryNumberViewModel
{
public Contact ContactToEdit {get; set;}
public PhoneNumber PhoneNumberToEdit {get;set;}
}
what would the edit(post) and edit(get) look like?
Any help would be appreciated to help me wrap my head around this ...
here is the Edit(get) modified to support if contact does not have phone number associated
' // GET: /Contact/Edit/5
public ActionResult Edit(int id = 0)
{
ContactPrimaryNumberViewModel ContactPrimaryNumber = (from pn in db.PhoneNumbers
where pn.ContactID == id && pn.Primary == true
select new ContactPrimaryNumberViewModel { ContactID = pn.ContactID, First_Name = pn.Contact.First_Name, Last_Name = pn.Contact.Last_Name, Number = pn.Number }).SingleOrDefault();
if (ContactPrimaryNumber == null)
{
ContactPrimaryNumber = (from c in db.Contacts
where c.ID == id
select new ContactPrimaryNumberViewModel { ContactID = c.ID, First_Name = c.First_Name, Last_Name = c.Last_Name, Number = null }).Single();
}
return View(ContactPrimaryNumber);
}'
so the final solution after everyones help is:
the models:
public class PhoneNumber
{
public int ID { get; set; }
public string Number { get; set; }
public bool Primary { get; set; }
[Required]
public int ContactID { get; set; }
public Contact Contact { get; set; }
}
public class Contact
{
public int ID { get; set; }
public string First_Name { get; set; }
public string Last_Name { get; set; }
public List<PhoneNumber> PhoneNumbers { get; set; }
}
The controler edit(get and post)
// GET: /Contact/Edit/5
public ActionResult Edit(int id = 0)
{
ContactPrimaryNumberViewModel ContactPrimaryNumber = (from c in db.Contacts
join pn in db.PhoneNumbers
on c.ID equals pn.ContactID into outer
from _pn in outer.Where(p => p.Primary ==true).DefaultIfEmpty()
where c.ID == id
select new ContactPrimaryNumberViewModel { ContactID = c.ID, First_Name = c.First_Name, Last_Name = c.Last_Name, Number = ((_pn == null) ? "" : _pn.Number) }).FirstOrDefault();
if (ContactPrimaryNumber == null)
{
return HttpNotFound();
}
return View(ContactPrimaryNumber);
}
// POST: /Contact/Edit/5
[HttpPost]
public ActionResult Edit(ContactPrimaryNumberViewModel ContactPrimaryNumber)
{
Contact c = db.Contacts.Find(ContactPrimaryNumber.ContactID);
PhoneNumber pn = db.PhoneNumbers.FirstOrDefault(x => x.ContactID == ContactPrimaryNumber.ContactID && x.Primary == true);
if (ModelState.IsValid)
{
c.First_Name = ContactPrimaryNumber.First_Name;
c.Last_Name = ContactPrimaryNumber.Last_Name;
if (pn == null) //if there is no phone number associated with the contact in the DB
{
if (!String.IsNullOrEmpty(ContactPrimaryNumber.Number))
{
//Add a new phonenumber in the database
PhoneNumber Px = new PhoneNumber();
Px.ContactID = ContactPrimaryNumber.ContactID;
Px.Number = ContactPrimaryNumber.Number;
Px.Primary = true;
db.PhoneNumbers.Add(Px);
}
}
else //if there is a phone number associated with the contactin the DB
{
if (String.IsNullOrEmpty(ContactPrimaryNumber.Number))
{
//delete the existing number
db.PhoneNumbers.Remove(pn);
}
else
{
//modify the existing number
pn.Number = ContactPrimaryNumber.Number;
}
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(c);
}
and the viewmodel
public class ContactPrimaryNumberViewModel
{
public int ContactID { get; set; }
public string First_Name { get; set; }
public string Last_Name { get; set; }
public string Number { get; set; }
}
thanks again for your help
I think your view model should look like this:
public class ContactPrimaryNumberViewModel
{
public int ID { get; set; }
public string First_Name { get; set; }
public string Last_Name { get; set; }
public string Number { get; set; }
}
And your update would look something like:
Contact c = context.Contacts.Find(id);
PhoneNumber p = context.PhoneNumbers
.FirstOrDefault(x => x.id == id && x.Primary == true);
//validate input
//update as necessary
//SaveChanges() etc...
from your comment - you new up the model class ContactPrimaryNumberViewModel:
var ContactPrimaryNumber =
from pn in db.PhoneNumbers
where pn.ContactID == id && pn.Primary == true
select new ContactPrimaryNumberViewModel() {
ContactID = pn.ContactID,
First_Name = pn.Contact.First_Name,
Last_Name = pn.Contact.Last_Name,
Number = pn.Number
};
Okay, try this:
PhoneNumber
public class PhoneNumber
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Number { get; set; }
public bool Primary { get; set; }
[ForeignKey("Contact"), DatabaseGenerated(DatabaseGeneratedOption.None)]
public int? ContactId { get; set; }
public virtual Contact Contact { get; set; }
}
Contact
public class Contact
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ContactId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<PhoneNumber> PhoneNumbers { get; set; }
}
SaveContact: depending on how you have set up your Repositories or Ef class. This can either go in your EfRepository implemention or your EfDb class.
public void SavePlayer(Contact contact)
{
using (var context = new EfDb())
{
if (contact.ContactId == 0)
{
context.Contacts.Add(contact);
}
else if (contact.ContactId > 0)
{
var currentContact = context.Contacts
.Include(c => c.PhoneNumber)
.Single(c => c.ContactId== contact.ContactId);
context.Entry(currentContact).CurrentValues.SetValues(contact);
currentContact.PhoneNumber= contact.PhoneNumber;
}
context.SaveChanges();
}
}
Edit action
[HttpGet]
public ActionResult Edit(int id)
{
var contact= _dataSource.Contacts.FirstOrDefault(c => c.Id == id);
return View(player);
}
[HttpPost]
public ActionResult Edit(Contact contact)
{
try
{
if (ModelState.IsValid)
{
_dataSource.SaveContact(contact);
return RedirectToAction("About", "Home");
}
}
catch (Exception)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
return View(contact);
}
Views
In your Contact View Folder add EditorTemplates folder. Then Scaffold a Create Strongly Typed PhoneNumber Partial View to this folder and name it PhoneNumber like its model.
Scaffold a Create Strongly Typed Contact View name it Create
Then add #Html.EditorFor(model => model.PhoneNumber) to the master Create View.

Categories

Resources