MVC 6 EF 7属性列表框未填充

时间:2016-01-31 21:28:08

标签: asp.net-core-mvc entity-framework-core asp.net-mvc-scaffolding

我已经尝试了一段时间来填充列表框,我似乎无法弄明白。我已经非常广泛地研究了实体框架7文档,但我还是新手。 MVC6 / EF7还没有很多教程,所以很难知道将一个实体类与另一个实体类相关联的最佳实践是什么。请原谅问题的长度,我只是想彻底解决。

我正在使用实体框架7,asp.net 5和MVC 6.

重现问题的步骤

  1. 创建新的 ASP.Net Web应用程序→项目名称: ListBox.Web →解决方案名称​​ ListBox
  2. 选择 APS.NET 5模板 Web应用程序
  3. Models 文件夹

    中创建两个类

    Parent.cs

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace ListBox.Web.Models
    {
        public class Parent
        {
            public int ParentId { get; set; }
            [Required]
            public string Name { get; set; }
            public ICollection<Child> Children { get; set; }
        }
    }
    

    Child.cs

    using System.ComponentModel.DataAnnotations;
    
    namespace ListBox.Web.Models
    {
        public class Child
        {
            public int ChildId { get; set; }
            [Required]
            public string Name { get; set; }
            public int ParentId { get; set; }
            public Parent Parent { get; set; }
        }
    }
    
  4. 使用scaffolding为每个数据类创建控制器和视图 Scaffolding Controller

  5. _Layout.cshtml

    中添加指向控制器的链接
                <ul class="nav navbar-nav">
                    <li><a asp-controller="Home" asp-action="Index">Home</a></li>
                    <li><a asp-controller="Parents" asp-action="Index">Parents</a></li>
                    <li><a asp-controller="Children" asp-action="Index">Children</a></li>
                    <li><a asp-controller="Home" asp-action="About">About</a></li>
                    <li><a asp-controller="Home" asp-action="Contact">Contact</a></li>
                </ul>
    
  6. 创建数据库

    ListBox\src\ListBox.Web>dns ef migrations add Initial
    ListBox\src\ListBox.Web>dnx ef database update     
    
  7. 运行Web应用程序

  8. 添加几个父母。

    enter image description here

  9. 尝试添加孩子。

    • 显示父母的下拉框,但下拉框中没有项目可供选择
    • enter image description here
    • 列表框的HTML为:<select class="form-control" data-val="true" data-val-required="The ParentId field is required." id="ParentId" name="ParentId"></select>
  10. 控制器源代码

    using System.Linq;
    using Microsoft.AspNet.Mvc;
    using Microsoft.AspNet.Mvc.Rendering;
    using Microsoft.Data.Entity;
    using ListBox.Web.Models;
    
    namespace ListBox.Web.Controllers
    {
        public class ChildrenController : Controller
        {
            private ApplicationDbContext _context;
    
            public ChildrenController(ApplicationDbContext context)
            {
                _context = context;    
            }
    
            // GET: Children
            public IActionResult Index()
            {
                var applicationDbContext = _context.Child.Include(c => c.Parent);
                return View(applicationDbContext.ToList());
            }
    
            // GET: Children/Details/5
            public IActionResult Details(int? id)
            {
                if (id == null)
                {
                    return HttpNotFound();
                }
    
                Child child = _context.Child.Single(m => m.ChildId == id);
                if (child == null)
                {
                    return HttpNotFound();
                }
    
                return View(child);
            }
    
            // GET: Children/Create
            public IActionResult Create()
            {
                ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent");
                return View();
            }
    
            // POST: Children/Create
            [HttpPost]
            [ValidateAntiForgeryToken]
            public IActionResult Create(Child child)
            {
                if (ModelState.IsValid)
                {
                    _context.Child.Add(child);
                    _context.SaveChanges();
                    return RedirectToAction("Index");
                }
                ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent", child.ParentId);
                return View(child);
            }
    
            // GET: Children/Edit/5
            public IActionResult Edit(int? id)
            {
                if (id == null)
                {
                    return HttpNotFound();
                }
    
                Child child = _context.Child.Single(m => m.ChildId == id);
                if (child == null)
                {
                    return HttpNotFound();
                }
                ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent", child.ParentId);
                return View(child);
            }
    
            // POST: Children/Edit/5
            [HttpPost]
            [ValidateAntiForgeryToken]
            public IActionResult Edit(Child child)
            {
                if (ModelState.IsValid)
                {
                    _context.Update(child);
                    _context.SaveChanges();
                    return RedirectToAction("Index");
                }
                ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent", child.ParentId);
                return View(child);
            }
    
            // GET: Children/Delete/5
            [ActionName("Delete")]
            public IActionResult Delete(int? id)
            {
                if (id == null)
                {
                    return HttpNotFound();
                }
    
                Child child = _context.Child.Single(m => m.ChildId == id);
                if (child == null)
                {
                    return HttpNotFound();
                }
    
                return View(child);
            }
    
            // POST: Children/Delete/5
            [HttpPost, ActionName("Delete")]
            [ValidateAntiForgeryToken]
            public IActionResult DeleteConfirmed(int id)
            {
                Child child = _context.Child.Single(m => m.ChildId == id);
                _context.Child.Remove(child);
                _context.SaveChanges();
                return RedirectToAction("Index");
            }
        }
    }
    

    Child Create.cshtml

    @model ListBox.Web.Models.Child
    
    @{
        ViewData["Title"] = "Create";
    }
    
    <h2>Create</h2>
    
    <form asp-action="Create">
        <div class="form-horizontal">
            <h4>Child</h4>
            <hr />
            <div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Name" class="col-md-2 control-label"></label>
                <div class="col-md-10">
                    <input asp-for="Name" class="form-control" />
                    <span asp-validation-for="Name" class="text-danger" />
                </div>
            </div>
            <div class="form-group">
                <label asp-for="ParentId" class="col-md-2 control-label"></label>
                <div class="col-md-10">
                    <select asp-for="ParentId" class ="form-control"></select>
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Create" class="btn btn-default" />
                </div>
            </div>
        </div>
    </form>
    
    <div>
        <a asp-action="Index">Back to List</a>
    </div>
    
    @section Scripts {
        <script src="~/lib/jquery/dist/jquery.min.js"></script>
        <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
        <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
    }
    

3 个答案:

答案 0 :(得分:2)

更改Create()中的ChildrenController方法,更改

    public IActionResult Create()
    {
        ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Parent");
        return View();
    }

    public IActionResult Create()
    {
        ViewData["ParentId"] = new SelectList(_context.Set<Parent>(), "ParentId", "Name");
        return View();
    }

Create.cshtml中,更改

<select asp-for="ParentId" class="form-control"></select>

@Html.DropDownList("ParentId", null, htmlAttributes: new { @class = "form-control" })

答案 1 :(得分:1)

生成的代码不正确,这是一个错误https://github.com/aspnet/Scaffolding/issues/149

使用&#34;标记助手的一种解决方案&#34;是:

控制器

...
ViewData["Parents"] = new SelectList(_context.Set<Parent>(), "ParentId", "Name", child.ParentId);
...

查看

@{
    var parents = (IEnumerable<SelectListItem>)ViewData["Parents"];
}
...
<select asp-for="ParentId" asp-items="parents" class ="form-control">
     <option disabled selected>--- SELECT ---</option>
</select>
...

答案 2 :(得分:0)

当只有一种类型的对象嵌套在同一类型的另一个对象中时,如何执行此操作。

对象:

public class Fleet
{

    public int Id { get; set; }
    public Fleet ParentFleet { get; set; }
    public int? ParentFleetId { get; set; }

    public string Name { get; set; }

    [InverseProperty("ParentFleet")]
    public virtual List<Fleet> Children { get; set; }

    public List<UserFleet> UserFleets { get; set; }
}

控制器:

ViewData["ParentFleetId"] = new SelectList(_context.Set<Fleet>(), "Id", "Name");
return View();

查看:

<form asp-action="Create">
    <div class="form-horizontal">
        <h4>Fleet</h4>
        <hr />
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Name" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="ParentFleet" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select asp-for="ParentFleetId" asp-items="ViewBag.ParentFleetId" class="form-control">
                    <option value=""></option>
                </select>
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
</form>