测试网站。以管理员身份登录时,用户应该能够删除服务。服务可以有子类别,称为"服务选项"以及"服务选项项目"。当管理员尝试永久删除服务时,他/她会收到以下服务器错误。
我做了一些研究,发现可能需要首先删除子类别,我相信代码反映了这一点。
控制器
//
// GET: /Service/Delete
[Authorize(Roles = "admin")]
public ActionResult Delete(int id)
{
Service serviceToDelete = db.Services.Where(s => s.ServiceId == id).Single();
return View(serviceToDelete);
}
//
// POST: /Service/Delete
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
var serviceToDelete = db.Services.Where(s => s.ServiceId == id).Single();
// remove the service option items
var serviceOptionItems = db.ServiceOptionItems.Where(soi => soi.ServiceOption.ServiceId == serviceToDelete.ServiceId);
foreach (var serviceOptionItem in serviceOptionItems)
{
db.ServiceOptionItems.Remove(serviceOptionItem);
}
// remove the service options
var serviceOptions = db.ServiceOptions.Where(so => so.ServiceId == serviceToDelete.ServiceId);
foreach (var serviceOption in serviceOptions)
{
db.ServiceOptions.Remove(serviceOption);
}
// remove the service
db.Services.Remove(serviceToDelete);
// save all changes
db.SaveChanges();
return RedirectToAction("Index", new { manage = "yes", mode = "all" });
}
查看
@model YardLad.Models.Domain.Service
@{
ViewBag.Title = "Delete Service";
}
<script>
$(document).ready(function () {
var isConfirmed = false;
$("form").submit(function (e) {
if (!isConfirmed)
{
$("#dialog-confirm").dialog({
resizable: false,
height: 140,
modal: true,
buttons: {
"Yes": function () {
$(this).dialog("close");
isConfirmed = true;
$("#deleteService").submit();
},
Cancel: function () {
$(this).dialog("close");
}
}
});
e.preventDefault();
return false;
}
else
{
return true;
}
});
});
</script>
<h2>Delete</h2>
<h3>Are you sure you want to delete this service?</h3>
<div class="display-label">Service Category</div>
<div class="display-field">
@Html.DisplayFor(m => m.ServiceCategory.Name)
</div>
<div class="display-label">Name</div>
<div class="display-field">
@Html.DisplayFor(m => m.Name)
</div>
<div class="display-label">Description</div>
<div class="display-field">
@if (Model.Description == null)
{
@:No Description
}
else
{
@Html.DisplayFor(m => m.Description)
}
</div>
<div class="display-label">Base Price</div>
<div class="display-field">
@Html.DisplayFor(m => m.BasePrice)
</div>
<div class="display-label">Is Active</div>
<div class="display-field">
@Html.DisplayFor(m => m.IsActive)
</div>
@using (Html.BeginForm("Delete", "Service", null, FormMethod.Post, new { id = "deleteService" }))
{
<p>
<input type="submit" id="btnSubmit" value="Delete" />
</p>
}
<div>
@Html.ActionLink("Back", "Index", new { manage = "yes" })
</div>
<div id="dialog-confirm" title="Delete this service?" class="hidden">
<p>This service will be permanently deleted and cannot be recovered. Are you sure?</p>
</div>
模型
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using YardLad.Models.Domain;
namespace YardLad.Models.View
{
public class ServiceViewModel
{
[Display(Name = "Service Id")]
public int ServiceId { get; set; }
[Required(ErrorMessage = "please enter a name")]
public string Name { get; set; }
[UIHint("multilinetext")]
public string Description { get; set; }
[Display(Name = "Base Price")]
public decimal BasePrice { get; set; }
[Display(Name = "Service Category")]
[Required(ErrorMessage = "please select a category")]
public int ServiceCategoryId { get; set; }
[Display(Name = "Is Active?")]
public bool IsActive { get; set; }
[Display(Name = "Service options")]
public List<ServiceOption> ServiceOptions { get; set; }
}
public class RequestServiceViewModel
{
[Required(ErrorMessage = "please select a state")]
public int StateId { get; set; }
[Required(ErrorMessage = "please select a service area")]
public int ServiceAreaId { get; set; }
[Required(ErrorMessage = "please select a service")]
public int ServiceId { get; set; }
[Required(ErrorMessage = "please indicate the items selected")]
public string[] SelectedServiceOptionItemIds { get; set; }
[Required(ErrorMessage = "please indicate the contractors available for the request")]
public string[] AvailableContractorIds { get; set; }
public State SelectedState { get; set; }
public ServiceArea SelectedServiceArea { get; set; }
public Service SelectedService { get; set; }
public List<ServiceOption> SelectedServiceOptions { get; set; }
public List<ServiceOptionItem> SelectedServiceOptionItems { get; set; }
public List<Contractor> AvailableContractors { get; set; }
public int SelectedContractorId { get; set; }
public Contractor SelectedContractor { get; set; }
public int SelectedContractorServiceId { get; set; }
public ContractorService SelectedContractorService { get; set; }
public decimal SubTotal { get; set; }
public decimal Tax { get; set; }
public decimal SelectedContractorTaxRate { get; set; }
public decimal Total { get; set; }
public bool UserIsLoggedIn { get; set; }
public int UserAddressId { get; set; }
public Address UserAddress { get; set; }
public bool CreateCustomAddress { get; set; }
public Address CustomAddress { get; set; }
}
public class SelectContractorViewModel
{
public int ServiceAreaId { get; set; }
public ServiceArea SelectedServiceArea { get; set; }
public int ServiceId { get; set; }
public Service SelectedService { get; set; }
public List<ServiceOption> ServiceOptions { get; set; }
public List<ServiceOptionItem> ServiceOptionItems { get; set; }
public List<Contractor> AvailableContractors { get; set; }
public Contractor SelectedContractor { get; set; }
public int ContractorTypeId { get; set; }
public int ContractorServiceId { get; set; }
public ContractorService SelectedContractorService { get; set; }
public List<ContractorServiceOption> ContractorServiceOptions { get; set; }
public List<ContractorServiceOptionItem> ContractorServiceOptionItems { get; set; }
public decimal SubTotal { get; set; }
public decimal Tax { get; set; }
public decimal SelectedContractorTaxRate { get; set; }
public decimal Total { get; set; }
}
}
数据库关系图: edmx
感谢您的阅读
答案 0 :(得分:0)
您对表Service
,ServiceOptions
和ServiceOptions
有外键约束。因此,您必须先删除该服务的所有ServiceOptionsItems
和ServiceOptions
,然后才能删除service
。
但是如果你有这样的要求,我建议你在添加约束时使用ON DELETE CASCADE
。因此,它允许您直接删除该服务,并会自动删除所有子ServiceOptions
和ServiceOptionsItems
。
答案 1 :(得分:0)
从错误消息中可以看出,Service
与ContractorService
之间存在关联。首先删除相关的ContactorService
实体,或删除或更改其ServiceId
值。
答案 2 :(得分:0)
您的Service
也与ContractorService
相关,并且必须有一些子记录才会导致您发布的错误。您需要像删除其他表一样删除所有这些子项,但您还需要将子实体设置为Deleted
:
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
var serviceToDelete = db.Services.Where(s => s.ServiceId == id).Single();
// remove the service option items
var serviceOptionItems = db.ServiceOptionItems.Where(soi => soi.ServiceOption.ServiceId == serviceToDelete.ServiceId);
foreach (var serviceOptionItem in serviceOptionItems)
{
db.ServiceOptionItems.Remove(serviceOptionItem);
db.Entry(serviceOptionItem).State = EntityState.Deleted;
}
// remove the service options
var serviceOptions = db.ServiceOptions.Where(so => so.ServiceId == serviceToDelete.ServiceId);
foreach (var serviceOption in serviceOptions)
{
db.ServiceOptions.Remove(serviceOption);
db.Entry(serviceOption).State = EntityState.Deleted;
}
// remove the contractor services
var contractorServices = db.ContractorServices.Where(so => so.ServiceId == serviceToDelete.ServiceId);
foreach (var contractorService in contractorServices)
{
db.ContractorServices.Remove(contractorService);
db.Entry(contractorService).State = EntityState.Deleted;
}
// remove the service
db.Services.Remove(serviceToDelete);
// save all changes
db.SaveChanges();
return RedirectToAction("Index", new { manage = "yes", mode = "all" });
}