Reputation: 28853
I have the following code in my 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");
}
And this is the view for the Edit method:
<% 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>
<% } %>
When I hit the submit button I get the error: Sequence contains no elements on this line: var originalArticle = (from m in _db.ArticleSet where m.storyId == ArticleToEdit.storyId select m).First();
What is the problem? How do I fix it. Thanks
Upvotes: 1
Views: 11682
Reputation: 47417
You need to be sure of is that when you're editing a record, you need to tell the database what record to edit. It's not enough to have the ID in the querystring unless you specifically tell the Model to use that ID (see my second option), however the easiest way to do that is add the field in your form.
<% 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>
<% } %>
This second option shows how to specify the storyId after the fact by submitting it to the Action via the Querystring. You just have to make sure the form action includes ?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);
}
}
I would also suggest using something like AutoMapper to map ArticleToEdit
to ArticleSet
so that you don't need to make an additional DB lookup just to grab the original article. Basically if you are able to map ArticleToEdit
to the ArticleSet
Model, then you can use LINQ to SQL to perform the update without first querying for the storyId.
Upvotes: 1
Reputation: 4221
You are not including the ID of the article in your HTML form. If you debug the ArticleToEdit object is probably either null or has zero storyId.
You should include your storyId in the HTML form. You can do it as a hidden field if you don't want the user to see it. For example:
<% using (Html.BeginForm()) {%>
<%= Html.HiddenFor("storyId") %>
...
On a separate note, you should probably switch to using Single instead of First. First indicates that you want the First item in a collection. Single indicates that you should get one and only one result.
Upvotes: 3
Reputation: 24754
The problem is you have nothing that matches your linq query in _db.ArticleSet
. First will throw against an empty collection.
Try FirstOrDefault()
if returning null is ok. FirstOrDetault()
will return null if nothing matches.
Upvotes: 3