我有以下课程
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; }
}
生成的CRUD视图页面。以下是来自控制器的编码代码:
[HttpPost]
public ActionResult Edit(News news)
{
if (ModelState.IsValid)
{
db.Entry(news).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(news);
}
当我尝试编辑记录时,收到以下错误:
将datetime2数据类型转换为日期时间数据类型会导致超出范围的值。
我将方法改为
[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);
}
尝试将ArticleDate属性设置为已存在的属性,但收到以下错误
声明已经终止。
ObjectStateManager中已存在具有相同键的对象。 ObjectStateManager无法使用相同的键跟踪多个对象。
我发现这个question是同样的错误(有趣的是他们也在处理文章)并且它提到错误是由于使用了ApplyPropertyChanges。
要在Edit.cshtml中添加,ArticleDate不会作为可编辑字段存在。
非常感谢帮助。
谢谢。
答案 0 :(得分:1)
通过从数据库加载,您可以将上一个日期的文章附加到上下文中。通过将news
对象的状态设置为Modified
,您将使用相同的键将第二个对象附加到被禁止的上下文并导致异常。
您可以使用:
var prevDate = db.NewsArticles
.Where(a => a.NewsId == news.NewsId)
.Select(a => a.ArticleDate)
.First();
这只加载来自数据库的日期而不加载整个对象,因此数据库中没有任何实体附加到上下文。
或者您可以使用:
[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);
}
修改强>
有关您的第一个例外的解释,请查看此问题及其答案:Using DateTime properties in Code-First Entity Framework and SQL Server