In the database I have have:
PK CountryID int notnull
PK ServiceID int notnull
PK TaskID int notnull
PK TaskItemID int notnull
PK CorrespondentID int notnull
PK PreviousTask int notnull
IsOnTimeline bit not null
..and 5 other nullable fields
I am using this composite key to ensure uniqueness of the "ServiceSchedule" item. The "Previoustask" field being a concatenation of all the PKs, the idea being that I can build a granular "ServiceSchedule" tasks timeline related from record to record.
The context is:
UPEntities db = new UPEntities(); for all workings here (i.e. repository and db).
The two Edit controller actions look like this:
public ActionResult Edit(int countryid,
int serviceid,
int taskid,
int taskitemid,
int correspondentid)
{
var t = (from s in repository.GetServiceSchedules()
where s.CountryID == countryid
where s.ServiceID == serviceid
where s.TaskID == taskid
where s.TaskItemID == taskitemid
where s.CorrespondentID == correspondentid
select s).First();
return View(t);
}
[HttpPost]
public ActionResult Edit(ServiceSchedule serviceToEdit)
{
var originalService = (from s in repository.GetServiceSchedules()
where s.CountryID == serviceToEdit.CountryID
where s.ServiceID == serviceToEdit.ServiceID
where s.TaskID == serviceToEdit.TaskID
where s.TaskItemID == serviceToEdit.TaskItemID
where s.CorrespondentID == serviceToEdit.CorrespondentID
select s).First();
if (!ModelState.IsValid)
return View(originalService);
db.ApplyPropertyChanges(originalService.EntityKey.EntitySetName, serviceToEdit); //Code throws exception here.......
db.SaveChanges();
return RedirectToAction("Index");
}
Everything seems to work OK up to the "db.ApplyPropertyChanges" line and there I get the error:
The ObjectStateManager does not contain an ObjectStateEntry with a reference to an object of type 'ProjectName.Models.ServiceSchedule'.
I have noticed that the model passed into the Edit View contains the collections from the related table (e.g. the countries collection off the CountryID) but when the model returns from the view it contains only the PK IDs from the "ServciceSchedule" table and no related collections.
I am currently trying to counter this problem by creating hiddenfors in the view like this but still cant seem to get the complete model back into the controller:
<% using (Html.BeginForm())
{%>
<%= Html.ValidationSummary(true)%>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%= Html.HiddenFor(model => model.CountryID)%>
</div>
<div class="editor-label">
<%= Html.HiddenFor(model => model.ServiceID)%>
</div>
<div class="editor-label">
<%= Html.HiddenFor(model => model.TaskID)%>
</div>
<div class="editor-label">
<%= Html.HiddenFor(model => model.TaskItemID)%>
</div>
<div class="editor-label">
<%= Html.HiddenFor(model => model.CorrespondentID)%>
</div>
<div class="editor-label">
<%= Html.HiddenFor(model => model.Services)%>
</div>
<div class="editor-label">
<%= Html.HiddenFor(model => model.Tasks)%>
</div>
<div class="editor-label">
<%= Html.HiddenFor(model => model.TaskItems)%>
</div>
<div class="editor-label">
<%= Html.HiddenFor(model => model.Correspondents)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.PreviousTask)%>
<%= Html.ValidationMessageFor(model => model.PreviousTask)%>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.Cost)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.Cost, String.Format("{0:F}", Model.Cost))%>
<%= Html.ValidationMessageFor(model => model.Cost)%>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.ChargeOut)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.ChargeOut, String.Format("{0:F}", Model.ChargeOut))%>
<%= Html.ValidationMessageFor(model => model.ChargeOut)%>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.DurationInDays)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.DurationInDays, String.Format("{0:F}", Model.DurationInDays))%>
<%= Html.ValidationMessageFor(model => model.DurationInDays)%>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.JobSection)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.JobSection)%>
<%= Html.ValidationMessageFor(model => model.JobSection)%>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.JobSectionGroup)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.JobSectionGroup)%>
<%= Html.ValidationMessageFor(model => model.JobSectionGroup)%>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
Also the GetServiceSchedules Repository looks like this:
public class ServicesRepository
{
UPEntities db = new UPEntities();
public List<ServiceSchedule> GetServiceSchedules()
{
return db.ServiceScheduleSet.Include("Countries")
.Include("Services")
.Include("Tasks")
.Include("TaskItems")
.Include("Correspondents")
.ToList();
}
}
(using VS 2008, SQL 2008, MVC2)
Can anyone let me know some more suggeted remedies?