0

I have the following class

public class News
{
    [Key]
    public int NewsId { get; set; }

    [Required(ErrorMessage = "The article title is required.")]
    [MaxLength(50)]
    public string Title { get; set; }

    [Required(ErrorMessage = "The article text is required.")]
    [UIHint("MultilineText")]
    [MaxLength(500)]
    public string Article { get; set; }

    [Display(Name = "Days to Expire")]
    public int DaysToExpire { get; set; }

    public DateTime ArticleDate { get; set; }
}

And the generated CRUD view pages. Here is the code from controller for editing:

    [HttpPost]
    public ActionResult Edit(News news)
    {
        if (ModelState.IsValid)
        {
            db.Entry(news).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(news);
    }

When I attempt to edit a record, I receive the following error:

The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.

I changed the method to

[HttpPost]
    public ActionResult Edit(News news)
    {
        if (ModelState.IsValid)
        {
            var prevDate = db.NewsArticles.First(a => a.NewsId == news.NewsId).ArticleDate;

            news.ArticleDate = prevDate;

            db.Entry(news).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(news);
    }

to try and set the ArticleDate property to what it already is, but received the following error

The statement has been terminated.

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

I found this question which is the same error (interestingly they were working with articles as well) and it mentions the error is due to ApplyPropertyChanges being used.

To add, in Edit.cshtml, the ArticleDate is not present as an editable field.

Help is appreciated.

Thank you.

Community
  • 1
  • 1
Erik
  • 279
  • 1
  • 3
  • 14

1 Answers1

1

You have the article with the previous date attached to the context by loading it from the DB. By setting the state of the news object to Modified you are attaching a second object with the same key to the context which is forbidden and causes the exception.

You can either use:

var prevDate = db.NewsArticles
    .Where(a => a.NewsId == news.NewsId)
    .Select(a => a.ArticleDate)
    .First();

This loads only the date from the DB but not the whole object, so no entity from the DB is attached to the context.

Or you can use:

[HttpPost]
public ActionResult Edit(News news)
{
    if (ModelState.IsValid)
    {
        var prevNews = db.NewsArticles.First(a => a.NewsId == news.NewsId);

        news.ArticleDate = prevNews.ArticleDate;

        db.Entry(prevNews).CurrentValues.SetValues(news);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(news);
}

Edit

For an explanation of your first exception take a look at this question and its answers: Using DateTime properties in Code-First Entity Framework and SQL Server

Community
  • 1
  • 1
Slauma
  • 175,098
  • 59
  • 401
  • 420