使用Entity Framework检测控制器中模型属性的状态更改

Cho*_*o87 7 asp.net-mvc entity-framework asp.net-mvc-3

我有一个或多或少的标准模型:

public class Project {
  public int ID { get; set; }
  //... some more properties

  public DateTime StartDate { get; set; }
  public int Duration { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

如果用户修改StartDate或投影Duration,我必须调用函数来更新模拟.为了实现这一点,我想检测字段StartDateDuration控制器内的状态变化.

像这样的东西:

if(project.StartDate.stateChange() || project.Duration.stateChange())
Run Code Online (Sandbox Code Playgroud)

以下是Controller Method的示例:

[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);
}
Run Code Online (Sandbox Code Playgroud)

任何想法,我怎样才能做到这一点?

Ste*_*asz 9

我相信你可以将编辑过的实体与从数据库中读取的原始实体进行比较.

就像是:

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 好吧,我站了修正,似乎工作,但不得不手工分配`original.value = project.value;`可能会有点乱,这可以通过替换`db.Entry(original).State = EntityState来解决.修改;`with`db.Entry(original).CurrentValues.SetValues(project);` (4认同)
  • @ Chopo87请尊重本网站的其他用户.如果您在回答中发现任何错误,请_edit并更正__.不要只在评论中留下"更新",因为评论是这里的二等公民,可能很容易被遗漏.始终尽量保持答案的准确性.谢谢. (2认同)

小智 8

您可以通过ViewBag携带旧值来解决它.

在行动:

public ActionResult Edit(int? id)
{
    //...Your Code
    ViewBag.OrigStartDate = project.StartDate;
    ViewBag.OrigDuration = project.Duration;
    return View(project);
}
Run Code Online (Sandbox Code Playgroud)

向View添加隐藏元素

...
@Html.Hidden("OrigStartDate", (DateTime)ViewBag.OrigStartDate)
@Html.Hidden("OrigDuration", (int)ViewBag.OrigDuration)
...
Run Code Online (Sandbox Code Playgroud)

将这些参数添加到post方法并检查它们的更改

[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);
}
Run Code Online (Sandbox Code Playgroud)