我仍然在学习很多关于实体框架及其如何通信的知识,所以这可能很简单,但我似乎无法弄清问题是什么。
要设置场景,我有一个由Visual Studio生成的工作Create函数,我在此函数中设置了如下值:
myObject.Id = Guid.NewGuid().ToString();
myObject.dateCreated = DateTime.Now;
这看起来很棒,而且一切正常。当我尝试编辑记录时出现问题。
我有这个型号:
public class MyObject
{
public string Id { get; set; }
public string UserId { get; set; }
public string Name { get; set; }
public DateTime dateCreated { get; set; }
public Nullable<DateTime> dateModified { get; set; }
public Boolean aDefault { get; set; }
}
(大部分是自动生成的)这些控制器:
public async Task<ActionResult> Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
MyObject myObject = await db.myObjects.FindAsync(id);
if (myObject == null)
{
return HttpNotFound();
}
return View(myObject);
}
public async Task<ActionResult> Edit([Bind(Include = "Id,aDefault,Name")] MyObject myObject)
{
if (ModelState.IsValid)
{
myObject.dateModified = DateTime.Now;
db.Entry(myObject).State = EntityState.Modified;
await db.SaveChangesAsync(); //db is the generated dbcontext
return RedirectToAction("Index");
}
return View(myObject);
}
并且(仅显示表单上的字段)视图:
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.aDefault, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
@Html.EditorFor(model => model.aDefault)
@Html.ValidationMessageFor(model => model.aDefault, "", new { @class = "text-danger" })
</div>
</div>
</div>
因此,当我运行此代码并转到编辑区域时,我希望它采用Name和默认值,将它们发布到控制器,并且只修改数据库中的相关字段。但是,目前当我运行此代码时,我得到:
将datetime2数据类型转换为日期时间数据类型会导致超出范围的值。 声明已经终止。
这让我相信我的dateCreated被设置为null。我通过使它成为Nullable来确认这一点,它不再抛出异常,但当然将数据库中的dateCreated设置为null。
我是否需要将所有属性绑定到视图,类似于在隐藏字段中设置Id的方式?我希望不是因为我想我只需要绑定相关的项目。有没有办法可以排除设置一次不更新的字段?
答案 0 :(得分:0)
感谢评论以及过去24小时的一些研究,我意识到主要问题是实体框架为我生成的问题。这条线让我头疼最多:
db.Entry(myObject).State = EntityState.Modified;
这会将所有属性设置为已修改,因此将所有值的值设置为null,并且未绑定的所有属性都保留为null。
我可以看到为什么另一个选项(也许更好的做法)可能只是为视图中的必要属性添加另一个ViewModel,但我想在这种情况下,控制器可能更适合实现正在改变的内容。这是我修改后的帖子方法:
public async Task<ActionResult> Edit([Bind(Include = "Id,aDefault,Name")] MyObject myObject)
{
if (ModelState.IsValid)
{
db.MyObjects.Attach(myObject); //MyObjects is the DbSet
myObject.dateModified = DateTime.Now;
db.Entry(myObject).Property(o => o.Name).IsModified = true;
db.Entry(myObject).Property(o => o.aDefault)IsModified = true;
await db.SaveChangesAsync(); //db is the generated dbcontext
return RedirectToAction("Index");
}
return View(myObject);
}