使用 DbContext 添加信息 - ASP.NET MVC

Adding information using DbContext - ASP.NET MVC

我正在完成学校的期末项目,但在完成时遇到了一些困难。

首先,我在以下 tutorial 的帮助下创建了一个网上商店。这是一个基于 MVC 3 的教程,但我是为最新版本制作的。

后来我想基于相同的原则制作某种博客-post 数据库,这就是我遇到麻烦的地方。

我已将文章制作为模型:

public class Article
{
    [Key]
    public int ArticleId { get; set; }
    public int SubjectId { get; set; }
    public string Title { get; set; }
    public string MainText { get; set; }
    public string PictureURL { get; set; }
    public ArticleSubject ArticleSubject { get; set; }
}

之后我创建了 ArticleSubject:

public class ArticleSubject
    {
        [Key]
        public int SubjectId { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public List<Article> Articles { get; set; }
    }

然后我创建了 NewsEntities DbContext:

public class NewsEntities : DbContext
{
    public DbSet<Article> Articles { get; set; }
    public DbSet<ArticleSubject> ArticleSubjects { get; set; }
}

最后我在"NewsData"class中填写了以下内容:

public class NewsData : DropCreateDatabaseIfModelChanges<NewsEntities>
{
    protected override void Seed(NewsEntities context)
    {
        var articleSubjects = new List<ArticleSubject>
        {
            new ArticleSubject { Title = "Almindelige Nyheder" },
            new ArticleSubject { Title = "Arrangementer" },
            new ArticleSubject { Title = "Udstillinger" }
        };
    }
}

然后我使用 Entity Framework 创建了一个 NewsManagerController。当我 运行 我的应用程序将创建新文章时,主题下拉列表为空。我一直在寻找一个没有任何运气的解决方案。

希望你能帮帮我!欢迎索取更多代码片段或信息。

谢谢!

//refnedergaard

编辑:

控制器:

public class NewsManagerController : Controller
{
    private NewsEntities db = new NewsEntities();

    // GET: NewsManager
    public ActionResult Index()
    {
        var articles = db.Articles.Include(a => a.ArticleSubject);
        return View(articles.ToList());
    }

    // GET: NewsManager/Details/5
    public ActionResult Details(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Article article = db.Articles.Find(id);
        if (article == null)
        {
            return HttpNotFound();
        }
        return View(article);
    }

    // GET: NewsManager/Create
    public ActionResult Create()
    {
        ViewBag.SubjectId = new SelectList(db.ArticleSubjects, "SubjectId", "Title");
        return View();
    }

    // POST: NewsManager/Create
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "ArticleId,SubjectId,Title,MainText,PictureURL")] Article article)
    {
        if (ModelState.IsValid)
        {
            db.Articles.Add(article);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        ViewBag.SubjectId = new SelectList(db.ArticleSubjects, "SubjectId", "Title", article.SubjectId);
        return View(article);
    }

    // GET: NewsManager/Edit/5
    public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Article article = db.Articles.Find(id);
        if (article == null)
        {
            return HttpNotFound();
        }
        ViewBag.SubjectId = new SelectList(db.ArticleSubjects, "SubjectId", "Title", article.SubjectId);
        return View(article);
    }

    // POST: NewsManager/Edit/5
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include = "ArticleId,SubjectId,Title,MainText,PictureURL")] Article article)
    {
        if (ModelState.IsValid)
        {
            db.Entry(article).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        ViewBag.SubjectId = new SelectList(db.ArticleSubjects, "SubjectId", "Title", article.SubjectId);
        return View(article);
    }

    // GET: NewsManager/Delete/5
    public ActionResult Delete(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Article article = db.Articles.Find(id);
        if (article == null)
        {
            return HttpNotFound();
        }
        return View(article);
    }

    // POST: NewsManager/Delete/5
    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public ActionResult DeleteConfirmed(int id)
    {
        Article article = db.Articles.Find(id);
        db.Articles.Remove(article);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }
}

创建视图:

    @model boerglumklosterdk.Models.Article

@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Create</h2>

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Article</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.SubjectId, "SubjectId", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("SubjectId", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.SubjectId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.MainText, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.MainText, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.MainText, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.PictureURL, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.PictureURL, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.PictureURL, "", new { @class = "text-danger" })
            </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>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

您创建了一个主题列表以添加到您的上下文中,但您从未将种子数据保存到您的上下文中。你可以试试:

public class NewsData : DropCreateDatabaseIfModelChanges<NewsEntities>
{
    protected override void Seed(NewsEntities context)
    {
        context.ArticleSubjects.AddOrUpdate(
            p => p.Title,
            new ArticleSubject { Title = "Almindelige Nyheder" },
            new ArticleSubject { Title = "Arrangementer" },
            new ArticleSubject { Title = "Udstillinger" }
        );
    }
}

我认为您的问题是因为您没有将 ArticleSubject 列表保存到数据库中。您需要先将它们添加到 ArticleSubjects DbSet,然后它们会调用上下文的 SaveChanges 方法:

context.ArticleSubjects.AddRange(articleSubjects);
context.SaveChanges();

现在,如果您使用 Migration,您不会在模型更改时删除数据库,因此您可能希望使用 @Sam 变体来避免重复。

此外,为了执行您的自定义初始化程序,您必须通过 Database 属性 设置数据库 Initializer

public class NewsEntities : DbContext
{
    public DbSet<Article> Articles { get; set; }
    public DbSet<ArticleSubject> ArticleSubjects { get; set; }

    public NewsEntities()
    {
      Database.SetInitializer(new NewsData());
    }
}