使用复杂的视图模型和交叉表生成带有MVC3的复选框列表

时间:2013-05-27 01:58:09

标签: asp.net-mvc-3

我继承了我的第一个MVC项目,它涉及在Linq to SQL之上使用MVC3。我一直试图找到一种方法来生成一个复选框列表,该列表基于涉及交叉表的多对多关系。

我有一个systemFailureType表,它通过交叉表映射到SystemFailureProblem表。

这是表格的设计师布局:

enter image description here

这里是我的视图模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using XNet.Repository.Model;

namespace XNet.WebUI.Hotel.ViewModel
{
    public class CheckFacilityVM
    {
        public int FacilityID { get; set; }
        public string facilityName { get; set; }
        public bool facilityAvailable { get; set; }

        public virtual Facility facility { get; set; }
        public virtual HotelFacility hotelfacility { get; set; }
    }
}

这是我的控制器

public ActionResult Facility()
        {
            ViewBag.hotel = _hotelService.GetByID(1).HotelName;

            var model = db.Facilities
                        .Select(htl => new CheckFacilityVM
                        {
                            FacilityID = htl.FacilityID,
                            facilityName = htl.FacilityName,
                            facilityAvailable = htl.IsActive,
                        })
                        .ToList();

            return View(model);
        }

这里是我的构造函数

public Facility ShowRoomFacility(int HotelID)
        {
            var x = (from d in db.Facilities
                     where d.FacilityID == HotelID
                     select d).FirstOrDefault();

            return x;
        }

我怎么能做到这一点......

1 个答案:

答案 0 :(得分:2)

我将为您提供一个简单,更常见的示例,您可以根据自己的需要进行调整 - 用户和角色(可以将用户分配给多个角色,同样角色也可以拥有多个用户)。

假设我们有一个“更新用户”表单,我们想要设置用户所属的角色。

这是控制器/视图模型的样子:

public class UsersController : Controller {

    [HttpGet]
    public ActionResult Update(int id) {
        var user = db.Users.Find(id);
        var model = new UsersUpdateModel {
            Name = user.Name,
            SelectedRoles = user.Roles.Select(r => r.Id).ToList(),
            Roles = GetRolesSelectList()
        };

        return View(model);
    }

    [HttpPost]
    public ActionResult Update(UsersUpdateModel model) {
        var user = db.Users.Find(model.Id);

        var roles = db.Roles.ToList();

        foreach (var role in roles) {
            if (model.SelectedRoles.Contains(role.Id)) {
                user.AddRole(role);
            }
            else {
                user.RemoveRole(role);
            }
        }
    }

    public SelectList GetRolesSelectList() {
        var roles = db.Roles.OrderBy(r => r.Name).ToList();
        return new SelectList(roles, "Id", "Name");
    }
}

public class UsersUpdateModel {
    public int Id { get; set; }
    public string Name { get; set; }
    public IEnumerable<int> SelectedRoles { get; set; }
    public SelectList Roles { get; set; }
}

基本上,您需要向视图模型添加属性以保存可用角色(在此示例中为“角色”),并且需要一个属性来保存所选角色(在此示例中为“SelectedRoles”)。

在您的POST操作中,您可以加载所有角色,如果UsersUpdateModel.SelectedRoles中存在ID,则将该角色添加到用户,否则将其删除。

我倾向于封装在拥有关系的一方添加/删除角色(或者它可能是什么集合)的过程 - 例如,User.AddRole可能会检查角色是否已经存在于防止添加两次:

public void AddRole(Role role) {
    var exists = this.Roles.FirstOrDefault(r => r.Id == role.Id);

    if (exists == null) {
        Roles.Add(role);
    }
}

最后,要创建复选框列表,您可以使用我创建的帮助程序here。它看起来像是:

@Html.CheckBoxListFor(model => model.SelectedRoles, Model.Roles)

这应该足以让你继续下去。请注意,代码是用记事本编写的,因此可能不是复制/可管理的。