我有一个数据库表,记录用户可以访问的出版物.该表非常简单 – 它只存储用户ID /发布ID对:
CREATE TABLE UserPublication (UserId INTEGER,PublicationID INTEGER)
给定用户的记录的存在&发布意味着用户有权访问;没有记录意味着无法访问.
我想向管理员用户提供一个简单的屏幕,允许他们配置用户可以访问的出版物.我想为每个可能的出版物显示一个复选框,并检查用户当前可以访问的出版物.然后,管理员用户可以检查或取消检查任意数量的出版物并提交表单.
有各种各样的出版物类型,我想将类似类型的出版物组合在一起 – 所以我确实需要控制出版物的呈现方式(我不想只是有一个平面列表).
我的视图模型显然需要有一个所有出版物的列表(因为我需要显示它们,无论当前选择如何),我还需要一个用户当前有权访问的出版物列表. (我不确定我是否会更好地使用单个列表,其中每个项目包括发布ID和是/否字段?).
但就我而言,这就是我的意思.我真的不知道如何将其绑定到一些复选框.我从哪里开始?
解决方法
您的问题的Linq to sql模型如下所示:
alt text http://i39.tinypic.com/m78d1y.jpg
首先,我们需要在数据模型中使用一些辅助对象:
namespace SelectProject.Models { public class UserPublicationSelector { public int UserPublicationID { get; set; } public int UserID { get; set; } public int PublicationID { get; set; } public string PublicationName { get; set; } public bool IsSelected { get; set; } } public class UserPublicationSelectviewmodel { public User User { get; set; } public IQueryable Selections { get; set; } } }
现在让我们创建一个如下所示的存储库:
public class Repository { DataContext dc = new DataContext(); public User GetUser(int userID) { return dc.Users.FirstOrDefault(u => u.UserID == userID); } public IQueryable GetUserPublications(int userID) { return from p in dc.Publications join up in dc.UserPublications on p.PublicationID equals up.PublicationID where up.UserID == userID orderby p.PublicationName select p; } public IQueryable GetUserPublicationSelectors(int userID) { return from p in dc.Publications join up in dc.UserPublications on p.PublicationID equals up.PublicationID into selected from s in selected.DefaultIfEmpty() orderby p.PublicationName select new UserPublicationSelector { UserPublicationID = (int?)s.UserPublicationID ?? 0,UserID = userID,PublicationID = p.PublicationID,PublicationName = p.PublicationName,IsSelected = s.UserID != null }; } public void UpdateUserPublications(UserPublicationSelector[] selections) { // Insert records for new selections... foreach (UserPublicationSelector selection in selections.Where(s => s.IsSelected == true)) { // ...where records do not yet exist in database. if (selection.UserPublicationID == 0) { UserPublication up = new UserPublication { UserID = selection.UserID,PublicationID = selection.PublicationID,}; dc.UserPublications.InsertOnSubmit(up); } } // Delete records for unselected items... foreach (UserPublicationSelector selection in selections.Where(s => s.IsSelected == false)) { // ...where record exists in database. if (selection.UserPublicationID > 0) { UserPublication up = dc.UserPublications.FirstOrDefault(s => s.UserPublicationID == selection.UserPublicationID); if (up.UserID == selection.UserID && up.PublicationID == selection.PublicationID) dc.UserPublications.DeleteOnSubmit(up); } } // Update the database dc.SubmitChanges(); } }
一个看起来像这样的控制器:
public class PublicationController : Controller { Repository repository = new Repository(); public ActionResult Index(int id) { User user = repository.GetUser(id); var publications = repository.GetUserPublications(id); ViewData["UserName"] = user.UserName; ViewData["UserID"] = user.UserID; return View("Index",publications); } [AcceptVerbs(HttpVerbs.Get)] public ActionResult Select(int id) { var viewmodel = new UserPublicationSelectviewmodel() { User = repository.GetUser(id),Selections = repository.GetUserPublicationSelectors(id) }; return View("Select",viewmodel); } [AcceptVerbs(HttpVerbs.Post)] public ActionResult Select(int userID,UserPublicationSelector[] selections) { repository.UpdateUserPublications(selections); return RedirectToAction("Index",new { id = userID }); } }
Index视图如下所示:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Publication>>" %> <%@ Import Namespace="SelectProject.Models" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> List of Selected Publications for User </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2>Publications for <%= ViewData["UserName"] %></h2> <table id="MyTable" style="width: 100%"> <thead> <tr> <th> Publication Name </th> </tr> </thead> <tbody> <% int i = 0; foreach (Publication item in Model) { %> <tr id="row<%= i.ToString() %>"> <td> <%= Html.Encode(item.PublicationName)%> </td> </tr> <% i++; } %> </tbody> </table> <p> <%= Html.ActionLink("Edit Selections","Select",new { id = ViewData["UserID"] })%> </p> </asp:Content>
Select视图如下所示:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<UserPublicationSelectviewmodel>" %> <%@ Import Namespace="SelectProject.Models" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Select Publications </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2>Select Publications for <%= Model.User.UserName %></h2> <% using (Html.BeginForm()) { %> <table id="MyTable" style="width: 100%"> <thead> <tr> <th style="width: 50px; text-align:center"> <input type="checkBox" id="SelectAll" /> </th> <th> Publication Name </th> </tr> </thead> <tbody> <% int i = 0; foreach (UserPublicationSelector item in Model.Selections) { %> <tr id="row<%= i.ToString() %>"> <td align="center" style="padding: 0 0 0 0"> <%= Html.CheckBox("selections[" + i.ToString() + "].IsSelected",item.IsSelected)%> <%= Html.Hidden("selections[" + i.ToString() + "].UserPublicationID",item.UserPublicationID)%> <%= Html.Hidden("selections[" + i.ToString() + "].UserID",Model.User.UserID)%> <%= Html.Hidden("selections[" + i.ToString() + "].PublicationID",item.PublicationID)%> </td> <td> <%= Html.Encode(item.PublicationName)%> </td> </tr> <% i++; } %> </tbody> </table> <p> <%= Html.Hidden("userID",Model.User.UserID) %> <input type="submit" value="save" /> </p> <% } // End Form %> <script src="../../Scripts/jquery-1.4.1.js" type="text/javascript"></script> <script type="text/javascript"> // Select All CheckBoxes $(document).ready(function() { $('#SelectAll').click(function() { var newValue = this.checked; $('input:checkBox').not('input:hidden').each(function() { this.checked = newValue; }); }); }); </script> </asp:Content>
这是一些屏幕截图.
alt text http://i43.tinypic.com/2yl07kw.jpg
alt text http://i44.tinypic.com/mhulua.jpg
左上角的复选框是Select All / Select None复选框.