Reputation: 75
I have a MVC application. I am having an issue with the Edit method. It is not posting back to the database. I added breakpoints and stepped through line by line and the value seems to update but it is not updating database. The database does not have a primary id field but the other fields (username,service, short_plan, role) are all PK. Ideas?
Model:
[MetadataType(typeof(Department_RolesMetadata))]
public partial class Department_Roles
{
}
public class Department_RolesMetadata
{
[Required]
public string username { get; set; }
[Required]
public string service { get; set; }
[Required]
public string short_plan { get; set; }
[Required]
public string role { get; set; }
}
Controller:
public ActionResult Edit(string username, string service, string sp, string role)
{
Department_Roles department_roles = db.Department_Roles.Where(dr => dr.username == username && dr.service == service && dr.short_plan == sp && dr.role == role).First();
ViewBag.username = new SelectList(db.Service_Logins, "username", "user_type", department_roles.username);
return View(department_roles);
}
[HttpPost]
public ActionResult Edit(Department_Roles department_roles)
{
if (ModelState.IsValid)
{
db.Department_Roles.Attach(department_roles);
db.Entry(department_roles).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.username = new SelectList(db.Service_Logins, "username", "user_type", department_roles.username);
return View(department_roles);
}
View:
@model NS.Models.Department_Roles
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Department</legend>
<div class="editor-label">
@Html.LabelFor(model => model.username)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.username,NS.Models.Department_Roles.GetServiceLogins(),"--Select One--")
@Html.ValidationMessageFor(model => model.username)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.service)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.service,NS.Models.Service_Logins.GetUserCompetitionTypes(),"--Select One--")
@Html.ValidationMessageFor(model => model.service)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.short_plan)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.short_plan,NS.Models.FeeAuth.GetActiveShortPlans(),"--Select One--")
@Html.ValidationMessageFor(model => model.short_plan)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.role)
</div>
<div class="editor-field">
@Html.DisplayFor(model => model.role)
@Html.HiddenFor(model => model.role)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "IndividualIndex", new { username = Model.username })
</div>
Upvotes: 0
Views: 1053
Reputation: 23680
The reason that this isn't working is because you're attempting to update the primary key values for the records in your database. It isn't possible to update PK values using entity framework because these are used to identify the records.
What I would suggest is having an Id
field as your primary key and if you need the columns that you have previously selected as your primary key to be unique, would be to add a unique constraint to your database that uses these columns. This way you will be able to update the values as they will no longer be PK values and you will have a unique constraint to keep your data intact.
Add an Id
value to your Department_Roles
class and change your PK to only use this value:
public class Department_Roles
{
// New Id value, this will be the primary key
public int Id { get; set; }
// ...
}
Then you can write something like this to retrieve, check the record with the selected Id
value exists and then update the row:
// Get an entity with all the required PK values
// In your example this will be the posted Department_Roles object
var departmentRole = new Department_Roles() { Id = 1 };
// Get the existing entry from the database
var existingDepartmentRole = dbContext.Department_Roles.Find(departmentRole.Id);
if (existingDepartmentRole == null)
{
throw new Exception("The existing department role could not be found using the PK values provided");
}
else
{
// Update the entry that we got out of the database and update the values
existingDepartmentRole.username = "bob";
existingDepartmentRole.role = "ProjectManager";
existingDepartmentRole.service = "Management";
existingDepartmentRole.short_plan = "permanant";
// Save the changes
dbContext.SaveChanges();
}
Upvotes: 0
Reputation: 1307
Have you tried getting the old value of the object from the database and use EF's dbContext.Entry(oldObject).CurrentValues.SetValues(updatedValues) and call SaveChnages after that? This microsoft article explain how to use the method.
Upvotes: 0
Reputation: 530
SQL PRIMARY KEY Constrain: The PRIMARY KEY constraint uniquely identifies each record in a database table. Primary keys must contain UNIQUE values. A primary key column cannot contain NULL values. Most tables should have a primary key, and each table can have only ONE primary key. So when you editing a your essence you are in fact created a new! If all four fields are primary keys It is a composite primary key. You have not any field outside the a composite key.
Upvotes: 1