Jam*_*esT 3 c# checkbox many-to-many entity-framework asp.net-mvc-4
我正在使用ASP.NET MVC 4和Entity Framework,我正在寻找一些方法来创建多个关系和我的数据库中的复选框,用于创建/编辑控制器和视图,我已经找到了@Slauma答案的答案创建MVC 4 -许多一对多的关系,复选框 ,但是,我真的很想看看这个延伸到编辑和删除的功能,以及想在这个解决方案的一些其他的合作伙伴.可能有人请告诉我怎么会填充在编辑控制器方法ClassificationSelectViewModel拿到两个"确认"和"取消选中"的价值观?这是一个Matt Flowers问题,也将解决我的问题.
Sla*_*uma 10
以下是延续这个答案描述Create
GET和与实体之间的许多一对多的关系POST行为的模型Subscription
和Company.
下面是该过程Edit
的行动我会怎么做(但我可能不会把所有的EF代码进入控制器操作,但将其提取到扩展和服务方法中):
将CompanySelectViewModel
保持不变:
public class CompanySelectViewModel
{
public int CompanyId { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这SubscriptionEditViewModel
是SubscriptionCreateViewModel
加号Subscription
的关键属性:
public class SubscriptionEditViewModel
{
public int Id { get; set; }
public int Amount { get; set; }
public IEnumerable<CompanySelectViewModel> Companies { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
该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);
}
Run Code Online (Sandbox Code Playgroud)
该Edit
视图是Create
视图加上了一个隐藏字段Subscription
的主要特性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")
}
Run Code Online (Sandbox Code Playgroud)
选择公司的编辑器模板保持不变:
@model CompanySelectViewModel
@Html.HiddenFor(model => model.CompanyId)
@Html.HiddenFor(model => model.Name)
@Html.LabelFor(model => model.IsSelected, Model.Name)
@Html.EditorFor(model => model.IsSelected)
Run Code Online (Sandbox Code Playgroud)
POST动作可能是这样的:
[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);
}
Run Code Online (Sandbox Code Playgroud)
该Delete
行动是那么困难.在GET
操作中,您可以加载一些订阅属性以显示在删除确认视图上:
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);
}
Run Code Online (Sandbox Code Playgroud)
然后在POST
操作中加载实体并将其删除.不需要包含公司,因为在多对多关系中(通常)启用链接表上的级联删除,以便数据库将负责与父级一起删除链接条目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");
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7669 次 |
最近记录: |