【问题标题】:ASP.Net MVC and state - How to update the database from Session changes in dual listboxes?ASP.Net MVC 和状态 - 如何从双列表框中的会话更改更新数据库?
【发布时间】:2015-05-17 05:10:05
【问题描述】:

我正在开发一个双列表框系统,操作员可以在该系统中为特定用户分配和删除不同的练习。对于 RemoveExercises 函数,我已经开始使用 Session 以便 RequestedExercises 列表框随着所做的更改(添加和删除练习)而更新。

目前AddExercises 函数将练习从AvailableExercises 列表框添加到数据库上的RequestedExercises 列表框(也称为RegimeItems),但它不会显示在RequestedExercises 列表框上,直到我返回页面。

但是,RemoveExercises 函数会从RequestedExercises 列表框中删除选定的练习,但不会对数据库进行更改。所以这两个函数只做了我希望它们做的一半,但方式不同。

这让我相信,由于会话状态,添加的练习没有显示在 RequestedExercises 列表框中,并且 RemoveExercises 没有更新其对数据库的更改。任何帮助将不胜感激。

更新:在帖子请求中将return View(model); 更改为return RedirectToAction("ExerciseIndex", new { id = model2.UserID, vmodel = model2 }); 后,添加练习效果很好。 我应该如何让 RemoveExercises 对域对象 User 起作用?

Controller.cs

    [HttpGet]
    public ActionResult ExerciseIndex(int id, UserExerciseViewModel vmodel)
    {
        User user = db.Users.Find(id);
        UserExerciseViewModel model = new UserExerciseViewModel { AvailableExercises = GetAllExercises(), RequestedExercises = ChosenExercises(user, vmodel) };
        model.UserID = user.UserID;
        Session["UserExerciseViewModel"] = model;
        return View(model);
    }

    [HttpPost]
    public ActionResult ExerciseIndex(UserExerciseViewModel model, string add, string remove, string send, int id, RegimeItem item)
    {
        UserExerciseViewModel model2 = (UserExerciseViewModel)(Session["UserExerciseViewModel"]);
        model.RequestedExercises = model2.RequestedExercises;
        model.AvailableExercises = model2.AvailableExercises;
        if (!string.IsNullOrEmpty(add))
            AddExercises(model, id);
        else if (!string.IsNullOrEmpty(remove))
            RemoveExercises(model, id);
        User user = db.Users.Find(model2.UserID);
        model2.RequestedExercises = ChosenExercises(user, model);
        user.RegimeItems = model.RequestedExercises;
        RestoreSavedState(model, user);
        return RedirectToAction("ExerciseIndex", new { id = model2.UserID, vmodel = model2 });
    )

    void RemoveExercises(UserExerciseViewModel model, int id)
    {
        var userExerciseViewModel = (UserExerciseViewModel)(Session["UserExerciseViewModel"]);
        foreach (int selected in model.RequestedSelected)
        {
            RegimeItem item = model.RequestedExercises.FirstOrDefault(i => i.RegimeItemID == selected);
            if (item != null)
            {
                model.RequestedExercises.Remove(item);
            }
        }
        db.SaveChanges();
    }

    void AddExercises(UserExerciseViewModel model, int id)
    {
        var userExerciseViewModel = (UserExerciseViewModel)(Session["UserExerciseViewModel"]);
        foreach (int selected in model.AvailableSelected)
        {
            if (model.AvailableSelected != null)
            {
                User user = db.Users.Find(id);
                user.RegimeItems.Add(new RegimeItem()
                {
                    RegimeExercise = (this.GetAllExercises().FirstOrDefault(i => i.ExerciseID == selected))
                });
            }
        }
        db.SaveChanges();
    }

    void RestoreSavedState(UserExerciseViewModel model, User user)
    {
        user.RegimeItems = this.ChosenExercises(user, model);
        if (!string.IsNullOrEmpty(model.SavedRequested))
        {
            string[] exIds = model.SavedRequested.Split(',');
            var regimeItems = ChosenExercises(user, model).Where(p => exIds.Contains(p.RegimeItemID.ToString()));
            model.RequestedExercises.AddRange(regimeItems);
        }
        db.SaveChanges();
    }

    private List<Exercise> GetAllExercises() //Gets all the data for AvailableExercises
    {
        return db.Exercises.ToList();
    }

    private List<RegimeItem> ChosenExercises(User user, UserExerciseViewModel model) //Gets all the data for RequestedExercies
    {
     return db.Users
     .Where(u => u.UserID == user.UserID)
     .SelectMany(u => u.RegimeItems)
     .ToList();
    }

模型(cs)

 public class User
    {
        public int UserID { get; set; }
        public ICollection<RegimeItem> RegimeItems { get; set; }
        public User()
        {
            this.RegimeItems = new List<RegimeItem>();
        } 
    }
    public class RegimeItem
    {
        public int RegimeItemID { get; set; }
        public Exercise RegimeExercise { get; set; }
    }

ViewModel(cs)

public class UserExerciseViewModel
{
    public List<Exercise> AvailableExercises { get; set; }
    public List<RegimeItem> RequestedExercises { get; set; }
    public int? SelectedExercise { get; set; }
    public int[] AvailableSelected { get; set; }
    public int[] RequestedSelected { get; set; }
    public string SavedRequested { get; set; }
    public int UserID { get; set; }
}

查看(仅分段(cshtml))

<td valign="top">
   @Html.ListBoxFor(model => model.AvailableSelected, new MultiSelectList(Model.AvailableExercises, "ExerciseID", "Name", Model.AvailableSelected))
</td>
<td valign="top">
  <input type="submit" name="add"
  id="add" value=">>" /><br />
  <input type="submit" name="remove"
  id="remove" value="<<" />
</td>
<td valign="top">
    @Html.ListBoxFor(model => model.RequestedSelected, new MultiSelectList(Model.RequestedExercises, "RegimeItemID", "RegimeExercise.Name", Model.RequestedSelected))
</td>

更新:将 RemoveExercises 更改为此可修复删除问题:

void RemoveExercises(UserExerciseViewModel model, int id)
{
    var userExerciseViewModel = (UserExerciseViewModel)(Session["UserExerciseViewModel"]);
    foreach (int selected in model.RequestedSelected)
    {
        if (model.RequestedSelected != null)
        {
            User user = db.Users.Find(id);
            RegimeItem item = db.RegimeItems.Find(selected);
            item.RegimeExercise = this.GetAllExercises().FirstOrDefault(i => i.ExerciseID == selected); //--this removes the regimeexercise
            user.RegimeItems.Remove(item); //deletes the user's regimeitem
            db.RegimeItems.Remove(item); //removes the regimeitem itself 
        }
    }
    db.SaveChanges();

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-4


    【解决方案1】:

    目前 AddExercises 函数从 AvailableExercises 列表框到 RequestedExercises 列表框(也 称为 RegimeItems),但它没有显示在 RequestedExercises 列表框,直到我返回页面。

    不会因为你不更新模型,只更新用户/数据库。

    void AddExercises(UserExerciseViewModel model, int id)
        {
            var userExerciseViewModel = (UserExerciseViewModel)(Session["UserExerciseViewModel"]);
            foreach (int selected in model.AvailableSelected)
            {
                if (model.AvailableSelected != null)
                {
                    User user = db.Users.Find(id);
                    user.RegimeItems.Add(new RegimeItem()
                    {
                        RegimeExercise = (this.GetAllExercises().FirstOrDefault(i => i.ExerciseID == selected))
                    });
                }
            }
            db.SaveChanges(); // db is updated but your model isn't
        }
    

    但是,RemoveExercises 函数会从 RequestedExercises 列表框,但不对 数据库。

    不会因为您只更新模型而不是用户。

     void RemoveExercises(UserExerciseViewModel model, int id)
        {
            var userExerciseViewModel = (UserExerciseViewModel)(Session["UserExerciseViewModel"]);
            foreach (int selected in model.RequestedSelected)
            {
                RegimeItem item = model.RequestedExercises.FirstOrDefault(i => i.RegimeItemID == selected);
                if (item != null)
                {
                    model.RequestedExercises.Remove(item);
                }
            }
            db.SaveChanges(); // What is the point of this? You didn't alter the user?
        }
    

    通常你会在这里做的是让AddRemove这两个方法都在域对象User上工作,这样数据库就会得到适当的更新,而不是

    return View(model)
    

    您将重定向到您的 GET 操作。

       return RedirectToAction("ExerciseIndex", new { id = model2.ID, vmodel= model2 });
    

    如果模型有您似乎没有检查的错误,您通常只会将模型返回到视图:

    if (ModelState.IsValid){ ...}
    

    还要注意如何找到用户。您在ExerciseIndex 中执行一次(无条件),然后在Remove 中再次执行。为什么不直接在ExerciseIndex 的顶部执行并传递给Remove

    【讨论】:

    • 感谢您,因此使用return RedirectToAction... AddExercises 可以完美运行。我应该如何使 RemoveExercises 在域对象User 上工作?
    • 将您的用户传递给user.RegimeItems.Remove
    猜你喜欢
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    相关资源
    最近更新 更多