2016-01-29 45 views
0

测试网站。以管理员身份登录时,用户应该能够删除服务。一个服务可以有子类别,称为“服务选项”,在其下面是“服务选项条目”。当管理员尝试永久删除服务时,他/她会收到以下服务器错误。MVC删除过程

Server Error

我做了一些研究,发现该子类可能需要先删除,而且我相信代码反映。

控制器

// 
    // 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; } 
} 
} 

DB关系的图片: edmx

临屋nk You for Reading

+1

问题是什么/问题? – 5uperdan

回答

0

您的ServiceContractorService也有关联,并且在那里必须有一些子记录导致您发布的错误。你需要像你这样的其他表中删除所有这些孩子,但你也需要设置儿童实体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" }); 
} 
0

对表ServiceServiceOptionsServiceOptions有外键约束。因此,您必须删除该服务的所有ServiceOptionsItemsServiceOptions,然后才能删除service

但是,如果您有这样的要求,我建议您在添加约束时使用ON DELETE CASCADE。这样它将允许您直接删除该服务,并自动删除所有子女ServiceOptionsServiceOptionsItems

更多信息:http://www.mysqltutorial.org/mysql-on-delete-cascade/

+0

谢谢你抽出时间帮助我。我认为每个循环都会循环并移除每个循环,然后才能移动到下一个循环? (serviceOptionItems中的serviceOptionItem) db.ServiceOptionItems.Remove(serviceOptionItem); } – Kane

+0

它应该但我可以说只有当你发布错误信息时你会得到更多。它不在你的问题。如果它与我所假设的错误相同,则可以尝试在每次循环后保存更改。 –

+0

我在原始文章中添加了服务器错误的图像。 – Kane

0

从错误信息,它看起来像你有Service和一些所谓ContractorService之间的关联。首先删除相关的ContactorService实体或删除或更改其值ServiceId值。