2016-01-29 42 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值。