![](/img/trans.png)
[英]How to delete object which is connected to another model with FK. ASP.NET Core MVC
[英]How to update object and its related object which are connected with FK. ASP.NET Core MVC
我想更新 object 及其與 FK 連接的相關對象。 例如,
我有 class 稱為“項目”
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace RandApp.Models
{
public class Item : BaseEntity
{
[Required]
[Display(Name = "Item Photo")]
public string ItemPhoto { get; set; }
[Required]
[Display(Name = "Item Type")]
public string ItemType { get; set; }
[Required]
[Display(Name = "Item Category")]
public string ItemCategory { get; set; }
[Required]
[Display(Name = "Item Name")]
public string Name { get; set; }
[Required]
[Display(Name = "Item Colors")]
public List<ItemColors> Color { get; set; } = new List<ItemColors>();
[Required]
[Display(Name = "Item Size")]
public List<ItemSizes> Size { get; set; } = new List<ItemSizes>();
[Required]
[Display(Name = "Item Material Type")]
public string MaterialType { get; set; }
[Required]
[Display(Name = "Designed For")]
public string DesignedFor { get; set; }
[Required]
[Display(Name = "Item Price")]
public double Price { get; set; }
[Required]
[Display(Name = "Item Description")]
public string Description { get; set; }
}
}
如您所見,我列出了“ItemColors”和“ItemSizes”類型,這些是它們的類ItemColors
using System.ComponentModel.DataAnnotations.Schema;
namespace RandApp.Models
{
public class ItemColors : BaseEntity
{
public string ItemColor { get; set; }
public int? ItemId { get; set; }
[ForeignKey("ItemId")]
public Item Item { get; set; }
}
}
物品尺寸
using System.ComponentModel.DataAnnotations.Schema;
namespace RandApp.Models
{
public class ItemSizes : BaseEntity
{
public string ItemSize { get; set; }
public int? ItemId { get; set; }
[ForeignKey("ItemId")]
public Item Item { get; set; }
}
}
所以我的下一個問題是:假設我已經創建了一些項目(例如運動衫)並且它有 colors:黑色,灰色,棕色並且它有尺寸:S,M。 因此,當我想更新此項目並添加一種顏色(如紅色或藍色)時,它不會更新,它只會在已存在的列表中添加此 colors 並重新上傳數據。 (如果我有黑色、灰色、棕色,然后添加紅色,現在我將有:“黑色、灰色、棕色、黑色、灰色、棕色、紅色”)。
有“項目”更新視圖:
@model RandApp.DTOs.ItemDto
<h4>Update Item</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="UpdateItem">
<input asp-for="Id" hidden />
<div class="form-group">
<label asp-for="@Model.ItemPhoto" class="control-label"></label>
<img src="~/assets/@Model.ItemPhoto" style="width:230px; height:300px; object-fit:cover" class="form-control" />
<input asp-for="@Model.ItemPhoto" hidden />
<span asp-validation-for="@Model.ItemPhoto" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="@Model.Name" class="control-label"></label>
<input asp-for="@Model.Name" class="form-control" />
<span asp-validation-for="@Model.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="@Model.DesignedFor" class="control-label"></label>
<select asp-for="@Model.DesignedFor" class="form-control">
@foreach (var desigendFor in Enum.GetValues(typeof(RandApp.Enums.DesignedFor)))
{
<option val="@desigendFor" value="@desigendFor.ToString()">@desigendFor</option>
}
</select>
<span asp-validation-for="@Model.DesignedFor" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="@Model.ItemCategory" class="control-label"></label>
<select asp-for="@Model.ItemCategory" class="form-control">
<option>@Model.ItemCategory</option>
</select>
<span asp-validation-for="@Model.ItemCategory" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="@Model.ItemType" class="control-label"></label>
<select asp-for="@Model.ItemType" class="form-control">
<option>@Model.ItemType</option>
</select>
<span asp-validation-for="@Model.ItemType" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="@Model.MaterialType" class="control-label"></label>
<select asp-for="@Model.MaterialType" class="form-control">
<option value="" selected>Select Material Type</option>
@foreach (var materialType in Enum.GetValues(typeof(RandApp.Enums.MaterialType)))
{
<option value="@materialType.ToString()">@materialType</option>
}
<option value="Other">Other</option>
</select>
<input id="otherMaterialInp" asp-for="@Model.MaterialType" class="form-control" style="display:none; margin-top:8px" placeholder="Enter Material Type" />
<span asp-validation-for="@Model.MaterialType" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="@Model.Color" class="control-label"></label>
<select asp-for="@Model.Color" class="form-control">
@foreach (var color in Enum.GetValues(typeof(RandApp.Enums.ItemColor)))
{
<option value="@color">@color</option>
}
<option value="Other">Other</option>
</select>
<!-- This hidden select is used to get only selected colors of current item -->
<select hidden multiple class="form-control" id="SelectedColors">
@foreach (var color in Model.Color)
{
<option value="@color.ItemColor">@color.ItemColor</option>
}
</select>
<span asp-validation-for="@Model.Color" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="@Model.Size" class="control-label"></label>
<select asp-for="@Model.Size" class="form-control">
</select>
<!-- This hidden select is used to get only selected sizes of current item -->
<select hidden multiple class="form-control" id="SelectedSizes">
@foreach (var size in Model.Size)
{
<option value="@size.ItemSize">@size.ItemSize</option>
}
</select>
<span asp-validation-for="@Model.Size" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="@Model.Price" class="control-label"></label>
<input asp-for="@Model.Price" class="form-control" />
<span asp-validation-for="@Model.Price" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="@Model.Description" class="control-label"></label>
<textarea asp-for="@Model.Description" class="form-control"></textarea>
<span asp-validation-for="@Model.Description" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Update" class="btn btn-primary" />
<a asp-controller="Admin" asp-action="Index" class="btn btn-primary">Go Back</a>
</div>
</form>
</div>
</div>
@section Scripts
{
<script>
var selectedItemTypeVal = $("#ItemType").val();
var selectedDesignedVal = $("#DesignedFor").val();
var selectedCategoryVal = $("#ItemCategory").val();
var itemColors = new Array();
var itemSizes = new Array();
$(document).ready(function () {
if ($("#DesignedFor").val() != "") {
$.ajax({
url: '@Url.Action("LoadItemCategories","Admin")',
type: 'GET',
dataType: 'json',
data: { designedFor: selectedDesignedVal },
success: function (res) {
$('#ItemCategory').html('');
$.each(res, function (val, text) {
$('#ItemCategory').append(
$('<option></option>').val(text).html(text)
);
});
},
error: function (err) {
console.log(err.responseText);
}
});
}
if ($("#ItemCategory").val() != "") {
$.ajax({
url: '@Url.Action("LoadItemTypes", "Admin")',
type: 'GET',
dataType: 'json',
data: { designedFor: selectedDesignedVal, category: selectedCategoryVal },
success: function (res) {
$('#ItemType').html('');
$.each(res, function (val, text) {
$('#ItemType').append(
$('<option></option>').val(text).html(text)
);
});
},
error: function (err) {
console.log(err.responseText);
}
});
}
if ($("#ItemType").val() != "") {
if (selectedCategoryVal.toLowerCase() == "clothing" || selectedCategoryVal.toLowerCase() == "shoes") {
$.ajax({
url: '@Url.Action("LoadItemSize", "Admin")',
type: 'GET',
dataType: 'json',
data: { designedFor: selectedDesignedVal, category: selectedCategoryVal },
success: function (res) {
$.each(res, function (val, text) {
$('#Size').append(
$('<option></option>').val(text).html(text)
);
itemSizes.push(text);
});
$("#SelectedSizes option").each(function () {
for (var i = 0; i < itemSizes.length; i++) {
if ($(this).val() == itemSizes[i]) {
$("[value=" + itemSizes[i] + "]").attr("selected", "selected");
}
}
});
},
error: function (err) {
console.log(err.responseText);
}
});
} else {
$.ajax({
url: '@Url.Action("LoadItemSizes", "Admin")',
type: 'GET',
dataType: 'json',
data: { designedFor: selectedDesignedVal, category: selectedCategoryVal, itemType: selectedItemTypeVal },
success: function (res) {
$.each(res, function (val, text) {
// This "1" means "SingleSize" enum value
if (text == 1) {
$('#Size').append(
$('<option></option>').val(text).html("Single Size")
);
} else {
$('#Size').append(
$('<option></option>').val(text).html(text + " CM")
);
}
});
},
error: function (err) {
console.log(err.responseText);
}
});
}
}
if ($("#Color option").val() != "") {
$("#Color option").each(function () {
itemColors.push($(this).val());
})
$("#SelectedColors option").each(function () {
for (var i = 0; i < itemColors.length; i++) {
if ($(this).val() == itemColors[i]) {
$("[value=" + itemColors[i] + "]").attr("selected", "selected");
}
}
});
}
});
function SetValue(input) {
var fileName = input.files[0].name;
//asp-for will generate the id and name
//so you can get the selector by using $("#ItemPhoto")
$("#ItemPhoto").val(fileName);
};
// displays "other option" input in order to enter custom material type
// if desired is not given in the list
$('#MaterialType').on('change', function () {
var selectedMaterialTypeVal = $(this).val();
if (selectedMaterialTypeVal.toLowerCase() == "other") {
$('#MaterialType').attr('disabled', 'disabled');
$('#otherMaterialInp').show();
} else {
$('#MaterialType').removeAttr('disabled');
$('#otherMaterialInp').hide();
}
});
</script>
}
並且有“項目” Controller
// GET Update
public async Task<IActionResult> UpdateItem(int id)
{
if (id == 0)
{
return NotFound();
}
var item = await _itemRepo.Get().Include(o => o.Color).Include(o => o.Size).FirstOrDefaultAsync(o => o.Id == id);
if (item == null)
{
return NotFound();
}
var result = _mapper.Map<ItemDto>(item);
return View(result);
}
// POST Update
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> UpdateItem(Item item, List<string> Color, List<string> Size)
{
if (!ModelState.IsValid)
{
return View();
}
foreach (var color in Color)
{
item.Color.Add(new ItemColors() { ItemId = item.Id, ItemColor = color });
}
foreach (var size in Size)
{
item.Size.Add(new ItemSizes() { ItemId = item.Id, ItemSize = size });
}
await _itemRepo.UpdateAsync(item);
return RedirectToAction("Index");
}
會不會是FK的問題? 或者是否有類似 Cascade Delete 的解決方案但用於更新或我能做什么?
您的代碼的行為是正確的,正如您所描述的那樣。
問題在於您的更新邏輯的實現。
最簡單但不是最好的解決方案是從項目中刪除所有 colors,然后添加參數中的所有內容。
我的建議是找到應該刪除的內容和應該添加的內容。 然后更新。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.