MVC 4编辑控制器/查看多对多关系和复选框 [英] MVC 4 Edit Controller/ View Many to Many relation and checkboxes
问题描述
我正在使用ASP.NET MVC 4和Entity Framework,我正在寻找一些方法来使我的db创建/编辑控制器和视图,使许多关系和复选框,我找到了答案与@ Slauma在 MVC 4 - 多对多关系和复选框中创建答案,但我真的想看看这个扩展到编辑和删除功能,以及像这个解决方案中的其他合作伙伴。有人可以请显示我如何填充ClassificationSelectViewModel在编辑控制器方法,以获得已选中和未选中值?这是一个马特花问题,这将解决我的太。
I'm working with ASP.NET MVC 4 and Entity Framework and I was searching for some way to make many to many relation and checkboxes from my db for a Create/Edit controller and view, I have found the answer with @Slauma answer for Create in MVC 4 - Many-to-Many relation and checkboxes but, I'd really like to see how this extends to Edit and Delete functionality as well like some other partners in this solution. Could someone please show how I would populate the ClassificationSelectViewModel in the Edit controller method to get both the "checked" and "unchecked" values? this is a Matt Flowers question that will solve mine too.
推荐答案
以下是此答案描述了对于具有多对多关系的模型的创建
GET和POST操作
和
公司。 >动作我将如何做(除了我可能不会把所有的EF代码到控制器动作,但提取它到扩展和服务方法):
The following is a continuation of this answer that describes Create
GET and POST actions for a model with many-to-many relationship between entities Subscription
and Company.
Here is the procedure for the Edit
actions how I would do it (except that I probably wouldn't put all the EF code into the controller actions but extract it into extension and service methods):
CompanySelectViewModel
保持不变:
public class CompanySelectViewModel
{
public int CompanyId { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
SubscriptionEditViewModel
是 SubscriptionCreateViewModel
加上订阅
的键属性:
public class SubscriptionEditViewModel
{
public int Id { get; set; }
public int Amount { get; set; }
public IEnumerable<CompanySelectViewModel> Companies { get; set; }
}
GET
动作可能如下所示:
public ActionResult Edit(int id)
{
// Load the subscription with the requested id from the DB
// together with its current related companies (only their Ids)
var data = _context.Subscriptions
.Where(s => s.SubscriptionId == id)
.Select(s => new
{
ViewModel = new SubscriptionEditViewModel
{
Id = s.SubscriptionId
Amount = s.Amount
},
CompanyIds = s.Companies.Select(c => c.CompanyId)
})
.SingleOrDefault();
if (data == null)
return HttpNotFound();
// Load all companies from the DB
data.ViewModel.Companies = _context.Companies
.Select(c => new CompanySelectViewModel
{
CompanyId = c.CompanyId,
Name = c.Name
})
.ToList();
// Set IsSelected flag: true (= checkbox checked) if the company
// is already related with the subscription; false, if not
foreach (var c in data.ViewModel.Companies)
c.IsSelected = data.CompanyIds.Contains(c.CompanyId);
return View(data.ViewModel);
}
编辑
是创建
视图以及订阅
的键属性的隐藏字段 Id
:
The Edit
view is the Create
view plus a hidden field for the Subscription
's key property Id
:
@model SubscriptionEditViewModel
@using (Html.BeginForm()) {
@Html.HiddenFor(model => model.Id)
@Html.EditorFor(model => model.Amount)
@Html.EditorFor(model => model.Companies)
<input type="submit" value="Save changes" />
@Html.ActionLink("Cancel", "Index")
}
用于选择公司的编辑器模板保持不变:
The editor template to select a company remains unchanged:
@model CompanySelectViewModel
@Html.HiddenFor(model => model.CompanyId)
@Html.HiddenFor(model => model.Name)
@Html.LabelFor(model => model.IsSelected, Model.Name)
@Html.EditorFor(model => model.IsSelected)
动作可能是这样的:
[HttpPost]
public ActionResult Edit(SubscriptionEditViewModel viewModel)
{
if (ModelState.IsValid)
{
var subscription = _context.Subscriptions.Include(s => s.Companies)
.SingleOrDefault(s => s.SubscriptionId == viewModel.Id);
if (subscription != null)
{
// Update scalar properties like "Amount"
subscription.Amount = viewModel.Amount;
// or more generic for multiple scalar properties
// _context.Entry(subscription).CurrentValues.SetValues(viewModel);
// But this will work only if you use the same key property name
// in ViewModel and entity
foreach (var company in viewModel.Companies)
{
if (company.IsSelected)
{
if (!subscription.Companies.Any(
c => c.CompanyId == company.CompanyId))
{
// if company is selected but not yet
// related in DB, add relationship
var addedCompany = new Company
{ CompanyId = company.CompanyId };
_context.Companies.Attach(addedCompany);
subscription.Companies.Add(addedCompany);
}
}
else
{
var removedCompany = subscription.Companies
.SingleOrDefault(c => c.CompanyId == company.CompanyId);
if (removedCompany != null)
// if company is not selected but currently
// related in DB, remove relationship
subscription.Companies.Remove(removedCompany);
}
}
_context.SaveChanges();
}
return RedirectToAction("Index");
}
return View(viewModel);
}
删除
不难。在 GET
操作中,您可以加载一些订阅属性以显示在删除确认视图上:
The Delete
actions are less difficult. In the GET
action you could load a few subscription properties to display on the delete confirmation view:
public ActionResult Delete(int id)
{
// Load subscription with given id from DB
// and populate a `SubscriptionDeleteViewModel`.
// It does not need to contain the related companies
return View(viewModel);
}
在 POST
动作加载实体,然后删除它。没有必要包括公司,因为在多对多关系(通常)中,链接表上的级联删除被启用,使得数据库将关心与父一起删除链接条目,订阅
:
And in the POST
action you load the entity and delete it then. There is no need to include the companies because in a many-to-many relationship (usually) cascading delete on the link table is enabled so that the database will take care of deleting the link entries together with the parent Subscription
:
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
var subscription = _context.Subscriptions.Find(id);
if (subscription != null)
_context.Subscriptions.Remove(subscription);
return RedirectToAction("Index");
}
这篇关于MVC 4编辑控制器/查看多对多关系和复选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!