不要过度依赖脚手架。关键是它为您提供了工作的基础;这不是你的观点的全部。您可以而且应该修改脚手架以满足您的需求,而且老实说,从头开始往往比尝试撤消脚手架添加的所有不必要的绒毛更容易。
也就是说,尤其是在一次选择多个相关项目时,您需要一个视图模型。尝试为此使用您的实体将很快失去动力。所以创建一个类:
public class GroupViewModel
{
// `Group` properties you need to edit here
public List<int> SelectedSubscriberIds { get; set; }
public IEnumerable<SelectListItem> SubscriberChoices { get; set; }
}
然后,在您的控制器中:
// We'll use this code multiple times so it's factored out into it's own method
private void PopulateSubscriberChoices(GroupViewModel model)
{
model.SubscriberChoices = db.Subscribers.Select(m => new SelectListItem
{
Value = m.Id.ToString(),
Text = m.FirstName + " " + m.LastName
});
}
public ActionResult Create()
{
var model = new GroupViewModel();
PopulateSubscriberChoices(model);
return View(model);
}
[HttpPost]
public ActionResult Create(GroupViewModel model)
{
if (ModelState.IsValid)
{
// Map the posted values onto a new `Group` instance. To set `Subscribers`,
// lookup instances from the database using the list of ids the user chose
var group = new Group
{
Name = model.Name,
Subscribers = db.Subscribers.Where(m => model.SelectedSubscriberIds.Contains(m.Id))
};
db.Groups.Add(group);
db.SaveChanges()
return RedirectToAction("Index");
}
PopulateSubscriberChoices(model);
return View(model);
}
public ActionResult Edit(int id)
{
var group = db.Groups.Find(id);
if (group == null)
{
return new HttpNotFoundResult();
}
// Map `Group` properties to your view model
var model = new GroupViewModel
{
Name = group.Name,
SelectedSubscriberIds = group.Subscribers.Select(m => m.Id).ToList()
};
PopulateSubscriberChoices(model);
return View(model);
}
[HttpPost]
public ActionResult Edit(int id, GroupViewModel model)
{
var group = db.Groups.Find(id);
if (group == null)
{
return new HttpNotFoundResult();
}
if (ModelState.IsValid)
{
group.Name = model.Name;
// Little bit trickier here
// First remove subscribers that are no longer selected
group.Subscribers.Where(m => !model.SelectedSubscriberIds.Contains(m.Id))
.ToList().ForEach(m => group.Subscribers.Remove(m));
// Now add newly selected subscribers
var existingSubscriberIds = group.Subscribers.Select(m => m.Id);
var newSubscriberIds = model.SelectedSubscriberIds.Except(existingSubscriberIds);
db.Subscribers.Where(m => newSubscriberIds.Contains(m.Id))
.ToList().ForEach(m => group.Subscribers.Add(m));
db.Entry(group).State = EntityState.Modified;
db.SaveChanges()
return RedirectToAction("Index");
}
PopulateSubscriberChoices(model);
return View(model);
}
编辑帖子操作是最困难的。为了不出现关于重复键等的错误,您需要确保不要将重复项添加到集合中。您还需要确保删除该组与用户未选择的任何项目之间的关系。除此之外,它非常简单。
最后在你的视图中,你只需要一个来渲染选择列表:
@model Namespace.To.GroupViewModel
...
@Html.ListBoxFor(m => m.SelectedSubscriberIds, Model.SubscriberChoices)
更新
添加转换后的 VB 代码。这可能无法 100% 开箱即用。任何有更多 VB 经验的人都可以随意编辑此内容以纠正任何问题。
查看模型
Public Class GroupViewModel
' Group properties you need to edit here
Public Property SelectedSubscriberIds As List(Of Integer)
Public Property SubscriberChoices As IEnumerable(Of SelectListItem)
End Class
控制器代码
' We'll use this code multiple times so it's factored out into it's own method
Private Sub PopulateSubscriberChoices(model As GroupViewModel)
model.SubscriberChoices = db.Subscribers.[Select](Function(m) New SelectListItem With { _
.Value = m.Id, _
.Text = m.FirstName & " " & m.LastName _
})
End Sub
Public Function Create() As ActionResult
Dim model as New GroupViewModel
PopulateSubscriberChoices(model)
Return View(model)
End Function
<HttpPost> _
Public Function Create(model As GroupViewModel) As ActionResult
If ModelState.IsValid Then
' Map the posted values onto a new `Group` instance. To set `Subscribers`,
' lookup instances from the database using the list of ids the user chose
Dim group = New Group With { _
.Name = model.Name, _
.Subscribers = db.Subscribers.Where(Function(m) model.SelectedSubscriberIds.Contains(m.Id)) _
}
db.Groups.Add(group)
db.SaveChanges()
Return RedirectToAction("Index")
End If
PopulateSubscriberChoices(model)
Return View(model)
End Function
Public Function Edit(id As Integer) As ActionResult
Dim group = db.Groups.Find(id)
If group Is Nothing Then
Return New HttpNotFoundResult()
End If
' Map `Group` properties to your view model
Dim model = New GroupViewModel With { _
.Name = group.Name, _
.SelectedSubscriberIds = group.Subscribers.[Select](Function(m) m.Id).ToList _
}
PopulateSubscriberChoices(model)
Return View(model)
End Function
<HttpPost> _
Public Function Edit(id As Integer, model As GroupViewModel) As ActionResult
Dim group = db.Groups.Find(id)
If group Is Nothing Then
Return New HttpNotFoundResult()
End If
If ModelState.IsValid Then
group.Name = model.Name
' Little bit trickier here
' First remove subscribers that are no longer selected
group.Subscribers.Where(Function(m) Not model.SelectedSubscriberIds.Contains(m.Id)).ToList().ForEach(Function(m) group.Subscribers.Remove(m))
' Now add newly selected subscribers
Dim existingSubscriberIds = group.Subscribers.[Select](Function(m) m.Id)
Dim newSubscriberIds = model.SelectedSubscriberIds.Except(existingSubscriberIds)
db.Subscribers.Where(Function(m) newSubscriberIds.Contains(m.Id)).ToList().ForEach(Function(m) group.Subscribers.Add(m))
db.Entry(group).State = EntityState.Modified
db.SaveChanges()
Return RedirectToAction("Index")
End If
PopulateSubscriberChoices(model)
Return View(model)
End Function