繁体   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