I have a more or less standard looking model:
public class Project {
public int ID { get; set; }
//... some more properties
public DateTime StartDate { get; set; }
public int Duration { get; set; }
}
If the user modifies StartDate
or project Duration
, I have to call a function to update a simulation. In order to achieve this I'd like to detect the state change of the fields StartDate
and Duration
within a controller.
Something like that:
if(project.StartDate.stateChange() || project.Duration.stateChange())
Here is an example of what the Controller Method would look like:
[HttpPost]
public ActionResult Edit(Project project)
{
if (ModelState.IsValid)
{
if(project.StartDate.stateChange() || project.Duration.stateChange())
doSomething();
db.Entry(project).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(project);
}
Any idea, how can I achieve this?
To track any entity by the context, it must have the primary key property. In Entity Framework, change tracking is enabled by default. You can also disable change tracking by setting the AutoDetectChangesEnabled property of DbContext to false. If this property is set to true then the Entity Framework maintains the state of entities.
Each entity has a state based on the operation performed on it via the context class. The entity state represented by an enum System.Data.Entity.EntityState in EF 6 and Microsoft.EntityFrameworkCore.EntityState in EF Core with the following values: The Context not only holds the reference to all the entity objects as soon as retrieved from ...
The Detached entity state indicates that the DbContext is not tracking the entity. Entity Framework Core Attach method allows us to attach an Detached entity to context and start tracking it. In the following code, we are attaching two entities ( Department1 & Department2 ).
You can change the state of an entity that is already being tracked by setting the State property on its entry. For example: Note that calling Add or Attach for an entity that is already tracked can also be used to change the entity state.
I believe you can compare the edited entity with the original one read from the database.
Something like:
public ActionResult Edit(Project project)
{
if (ModelState.IsValid)
{
var original = db.Find(project.ID);
bool changed = original.StartDate != project.StartDate || original.Duration != project.Duration;
if (changed)
{
original.StartDate = project.StartDate;
original.Duration = project.Duration;
doSomething();
db.Entry(original).CurrentValues.SetValues(project);
db.SaveChanges();
}
}
return View(project);
}
You can solve it by carrying old values via ViewBag.
In action:
public ActionResult Edit(int? id)
{
//...Your Code
ViewBag.OrigStartDate = project.StartDate;
ViewBag.OrigDuration = project.Duration;
return View(project);
}
Add hidden elements to View
...
@Html.Hidden("OrigStartDate", (DateTime)ViewBag.OrigStartDate)
@Html.Hidden("OrigDuration", (int)ViewBag.OrigDuration)
...
Add these parameters to the post method and check them for changes
[HttpPost]
public ActionResult Edit(DateTime OrigStartDate, int OrigDuration)
{
if (ModelState.IsValid)
{
if (OrigStartDate != project.StartDate || OrigDuration != project.Duration)
doSomething();
db.Entry(project).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.FileTypeId = new SelectList(db.FileTypes, "Id", "TypeName", dbinfo.FileTypeId);
return View(project);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With