簡體   English   中英

在 ASP.NET 核心 MVC 問題中添加多對多關系中的項目集合(代碼優先)

[英]Adding collection of items in Many to Many Relationship in ASP.NET Core MVC Problem (Code first)

我有兩個具有多對多關系的實體,Book 和 Tags asp 使用代碼優先方法為這兩個實體自動創建了一個表

  1. 我試圖在書籍創建中添加標簽集合,但標簽項是 null 也有(選擇 asp-for="Tags" )但它在[httppost]create中顯示 null 。

  2. 我試圖通過上下文添加它,因為它捕獲了我添加的標簽的值,但是出現錯誤

    無法將……dbset<> 轉換為 Models.tags

代碼:

public class Book
{
    public int BookID { get; set; }
    [Required]
    public string Name { get; set; } = null!;

    //Navigation property
    public virtual ICollection<Tags>? Tags { get; set; }   
}

public class Tags
{
    public int TagsID { get; set; } 
    public string TagName { get; set; } = null!;

    //Navigation property
    public virtual ICollection<Book>? Book { get; set; }
}

//DB Context
public class BLabContext: DbContext
{
    public DbSet<Book> Book { get; set; }   
    public DbSet<Tags> Tags { get; set; } 
}

// Book Controller
public class BooksController : Controller
{
    private readonly BLabContext _context;

    public BooksController(BLabContext context)
    {
        _context = context;
    }

    // Tags objects
   
    // public ICollection<Tags> Tags { get; set; }
   
    // GET: Books
    public async Task<IActionResult> Index()
    {
        return View(await _context.Book.ToListAsync());
    }

    // GET: Books/Create

(獲取時)public IActionResult Create() { /// var tags = _context.Tags.ToList(); ViewData["標簽"] = 標簽; //ViewBag.tags = tags;

        return View();
    }

    // POST: Books/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create([Bind("BookID,Name,Description,PublishedOn,Publisher,Price,ImageURL,1)💀Tags💀")] Book book)
    {
        if (ModelState.IsValid)
        {

2) var 標簽 = _context.Tags; _context.Add(書籍); 等待 _context.SaveChangesAsync();

2)(無法將……dbset<> 轉換為 Models.tags

            _context.Book.FirstOrDefault(b => b.BookID == book.BookID).Tags.Add(tags);

            await _context.SaveChangesAsync();

            return RedirectToAction(nameof(Index));
        }
        return View(book);
    }

創建視圖:

@using Book_Library.Models;
@model Book_Library.Models.Book

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Book</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create" enctype="multipart/form-data">

            <div asp-validation-summary="ModelOnly" class="text-danger"></div>

            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>

            @*    ///💀💀💀💀💀💀💀*@
            <div class="form-group">
                <label asp-for="Tags" class="control-label"></label>

                @*name="Tags"*@
                <select asp-for="Tags" multiple>
                    @foreach (var tag in @ViewData["tags"] as IList<Tags>)
                    {
                        <option value="@tag.TagName">@tag.TagName </option>
                    }
                    </select>
            </div>


            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

我希望在創建的書中添加標簽集合,並在詳細信息視圖中查看這些標簽

你可以創建一個ViewModel來實現它,請參考這個demo:

視圖模型

public class CreateBookViewModel
    {
        [Required]
        public string BookName { get; set; }
        public List<int> TagId { get; set; }
    }

Controller

public IActionResult Create()
        {  
            var tags = _context.Tags.ToList();

            List<SelectListItem> dropdown = new List<SelectListItem>();
            foreach (var item in tags)
            {
                var listItem = new SelectListItem();
                listItem.Text = item.TagName;
                listItem.Value = item.TagsID.ToString();
                dropdown.Add(listItem);
            }
           
            ViewBag.tags = dropdown;

            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(CreateBookViewModel book)
        {
            if (ModelState.IsValid)
            {
                Book b = new Book();
                b.Name = book.BookName;
                if (book.TagId.Count>0)
                {
                    foreach (var item in book.TagId)
                    {
                        var tag = _context.Tags.Where(x => x.TagsID == item).FirstOrDefault();
                        b.Tags.Add(tag);
                    }
                }

                _context.Book.Add(b);

                await _context.SaveChangesAsync();

                return RedirectToAction(nameof(Index));
            }
            return View(book);
        }

看法

@model CreateBookViewModel

@{
    ViewData["Title"] = "Create";
   
}

<h1>Create</h1>

<h4>Book</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create" enctype="multipart/form-data">

            <div asp-validation-summary="ModelOnly" class="text-danger"></div>

            <div class="form-group">
                <label asp-for="BookName" class="control-label"></label>
                <input asp-for="BookName" class="form-control" />
                <span asp-validation-for="BookName" class="text-danger"></span>
            </div>

            
            <div class="form-group">
                <label asp-for="@Model.TagId" class="control-label"></label>


                <select asp-for="@Model.TagId" asp-items="@ViewBag.tags" multiple></select>
            </div>


            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{
        await Html.RenderPartialAsync("_ValidationScriptsPartial");
    }
}

現在,您可以成功地將標簽集合添加到圖書中。

在此處輸入圖像描述

注意:你需要實例化你的Book class中的Tags,否則上面的代碼會報nullreferenceexception

 public class Book
    {
        //.........

        //Navigation property
        public virtual ICollection<Tags>? Tags { get; set; }  = new List<Tags>();
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM