ASP.NET MVC Sequence不包含任何元素

时间:2011-01-05 19:32:55

标签: asp.net-mvc

我的HomeController中有以下代码:

    public ActionResult Edit(int id)
    {
        var ArticleToEdit = (from m in _db.ArticleSet where m.storyId == id select m).First();
        return View(ArticleToEdit);
    }

    [ValidateInput(false)]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(Article ArticleToEdit)
    {

        var originalArticle = (from m in _db.ArticleSet where m.storyId == ArticleToEdit.storyId select m).First();
        if (!ModelState.IsValid)
            return View(originalArticle);

        _db.ApplyPropertyChanges(originalArticle.EntityKey.EntitySetName, ArticleToEdit);
        _db.SaveChanges();
        return RedirectToAction("Index");

    }

这是Edit方法的视图:

<% using (Html.BeginForm()) {%>

    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="headline">Headline</label>
            <%= Html.TextBox("headline") %>
        </p>
        <p>
            <label for="story">Story <span>( HTML Allowed )</span></label>
            <%= Html.TextArea("story") %>
        </p>
        <p>
            <label for="image">Image URL</label>
            <%= Html.TextBox("image") %>
        </p>
        <p>
            <input type="submit" value="Post" />
        </p>
    </fieldset>

<% } %>

当我点击提交按钮时,我收到错误:序列在此行中不包含任何元素:var originalArticle = (from m in _db.ArticleSet where m.storyId == ArticleToEdit.storyId select m).First();

有什么问题?我如何解决它。感谢

3 个答案:

答案 0 :(得分:3)

问题是你没有任何东西与_db.ArticleSet中的linq查询相匹配。首先是反对空集合。

如果返回null,则尝试FirstOrDefault()。如果没有匹配,FirstOrDetault()将返回null。

答案 1 :(得分:3)

您未在HTML表单中包含文章的ID。如果您调试ArticleToEdit对象可能为null或者没有storyId。

您应该在HTML表单中包含您的storyId。如果您不希望用户看到它,您可以将其作为隐藏字段。例如:

<% using (Html.BeginForm()) {%>
    <%= Html.HiddenFor("storyId") %>
    ...

另外,您应该切换到使用Single而不是First。首先表明您想要集合中的第一项。单表示您应该只获得一个结果。

答案 2 :(得分:1)

您需要确定的是,当您编辑记录时,您需要告诉数据库要编辑的记录。除非您明确告诉模型使用该ID(参见我的第二个选项),否则在查询字符串中使用ID是不够的,但最简单的方法是在表单中添加字段。

<% using (Html.BeginForm()) {%>
<%= Html.HiddenFor("storyId") %>
    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="headline">Headline</label>
            <%= Html.TextBox("headline") %>
        </p>
        <p>
            <label for="story">Story <span>( HTML Allowed )</span></label>
            <%= Html.TextArea("story") %>
        </p>
        <p>
            <label for="image">Image URL</label>
            <%= Html.TextBox("image") %>
        </p>
        <p>
            <input type="submit" value="Post" />
        </p>
    </fieldset>

<% } %>

第二个选项显示如何通过Querystring将StoryId提交给Action来指定storyId。您只需确保表单操作包含?storyId=[n]

[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Article ArticleToEdit, int storyId)
{

    ArticleToEdit.storyId = storyId;

    if (ModelState.IsValid) {
        _db.ApplyPropertyChanges(originalArticle.EntityKey.EntitySetName, ArticleToEdit);
        _db.SaveChanges();
        return RedirectToAction("Index");

    } else {
        return View(ArticleToEdit);
    }
}

我还建议使用AutoMapper之类的内容将ArticleToEdit映射到ArticleSet,这样您就不需要进行额外的数据库查找就可以获取原始文章。基本上,如果您能够将ArticleToEdit映射到ArticleSet模型,那么您可以使用LINQ to SQL来执行更新,而无需先查询storyId。