我使用的是ASP.Net MVC 5和EF6
我有一个叫DoodleBug的模型(不要问)。当我尝试创建这个实体的一个新条目并将其保存到数据库中时,我会得到以下异常,即使我没有输入Id值?
SqlException: Cannot insert explicit value for identity column in table
'DoodleBugs' when IDENTITY_INSERT is set to OFF.这是我的模型
public class DoodleBug
{
public int Id { get; set; }
public string Sentence { get; set; }
public DateTime Adate { get; set; }
public Boolean TrueFalse { get; set; }
public int DoodleId { get; set; }
public int BugId { get; set; }
public virtual Doodle Doodle { get; set; }
public virtual Bug Bug { get; set; }
}这是控制器
// GET: DoodleBugs/Create
public ActionResult Create()
{
ViewBag.Id = new SelectList(db.Bug, "Id", "BugString");
ViewBag.Id = new SelectList(db.Doodle, "Id", "DoodleString");
return View();
}
// POST: DoodleBugs/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Sentence,Adate,TrueFalse,DoodleId,BugId")] DoodleBug doodleBug) // Edited FROM [Bind(Include = "Id,Sentence,Adate,TrueFalse,DoodleId,BugId")] ---- removed Id from bind list
{
if (ModelState.IsValid)
{
db.DoodleBug.Add(doodleBug);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.Id = new SelectList(db.Bug, "Id", "BugString", doodleBug.Id);
ViewBag.Id = new SelectList(db.Doodle, "Id", "DoodleString", doodleBug.Id);
return View(doodleBug);
}这是一幅风景
<div class="form-horizontal">
<h4>DoodleBug</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@*<div class="form-group">
@Html.LabelFor(model => model.Id, "Id", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("Id", null, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Id, "", new { @class = "text-danger" })
</div>
</div>*@
<div class="form-group">
@Html.LabelFor(model => model.Sentence, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Sentence, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Sentence, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Adate, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Adate, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Adate, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.TrueFalse, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
@Html.EditorFor(model => model.TrueFalse)
@Html.ValidationMessageFor(model => model.TrueFalse, "", new { @class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.DoodleId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.DoodleId, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.DoodleId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.BugId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.BugId, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.BugId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}如果有帮助,下面是为DoodleBug实体生成的EF迁移代码。我手动更改了一些代码线,如它们旁边的注释所指出的,以便在DoodleBug实体和另外两个实体(Doodle和Bug)之间创建一个外键关系。
CreateTable(
"dbo.DoodleBugs",
c => new
{
Id = c.Int(nullable: false, identity: true), // Edited FROM 'Id = c.Int(nullable: false)'
Sentence = c.String(),
Adate = c.DateTime(),
TrueFalse = c.Boolean(),
DoodleId = c.Int(nullable: false),
BugId = c.Int(nullable: false),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Bugs", t => t.BugId) // Edited FROM 'ForeignKey("dbo.Bugs", t => t.Id)'
.ForeignKey("dbo.Doodles", t => t.DoodleId) // Edited FROM 'ForeignKey("dbo.Doodles", t => t.Id)'
.Index(t => t.Id)
.Index(t => t.BugId) // Added
.Index(t => t.DoodleId); // AddedNB控制器和视图是由EF搭建的,EF为create()方法中的ID添加了一个SelectList属性,在控制器ViewBag中为Id添加了一个项的SelectList,以及视图中的一个表单控件来使用控制器中的SelectList创建一个下拉列表选项,以输入Id值。
我删除了控制器Create()方法中的Bind属性中的Id,并注释掉了视图中与Id值相关的表单控件(如视图中第5-11行中的@* - *@所示)。
尽管如此,当我运行代码并尝试提交表单时,我得到了上面的错误吗?
当我在调试模式下运行应用程序时,doodleBug变量的属性框的Id值为0 (Int)。我不知道这是从哪里来的,还是它是一个默认值?
在回答下面的问题时,是涂鸦和Bug模型
public class Doodle
{
public int Id { get; set; }
public string DoodleString { get; set; }
public DateTime DoodleTime { get; set; }
public Boolean DoodleBool { get; set; }
public virtual DoodleBug DoodleBUg { get; set; }
}
public class Bug
{
public int Id { get; set; }
public string BugString { get; set; }
public DateTime BugTime { get; set; }
public Boolean BugBool { get; set; }
public virtual DoodleBug DoodleBug { get; set; }
}我也有一些fluent API试图创建1到- 0/1的关系,DoodleBug实体是两者的可选实体。
// 1 - 2 - 0/1
modelBuilder.Entity<DoodleBug>()
.HasRequired(db => db.Doodle)
.WithOptional(d => d.DoodleBUg);
modelBuilder.Entity<DoodleBug>()
.HasRequired(db => db.Bug)
.WithOptional(b => b.DoodleBug);不确定这是否是您的意思,问我的DB结构是什么,但复制了这个打开sqlexpress;
dbo.DoodlBugs
Columns:
Id (PK, int, not null)
Sentence (nvarchar(max), null)
Adate (datetime, null)
TrueFalse (bit, null)
DoodleId (FK, int, not null)
BugId (FK, int, not null)
Keys
PK_dbo.DoodleBugs
FK_dbo.DoodleBugs_dbo.Bugs_BugId
FK_dbo.DoodleBugs_dbo.Doodles_DoodleId发布于 2017-08-13 01:41:07
正如我在注释中提到的,您必须手动修改生成的迁移,这表明模型中存在问题。
例如,此编辑
Id = c.Int(nullable: false, identity: true), // Edited FROM 'Id = c.Int(nullable: false)'迁移是基于该模型生成的。这里需要注意的是,从EF的角度来看,Id字段是而不是标识。虽然您的编辑固定了数据库字段,但对于EF,该字段仍然是而不是标识,因此EF不将其视为标识和相关行为,比如在执行INSERT时不传递值,而是像常规int字段一样将其值(在默认情况下为0)传递给INSERT命令,从而导致正在获得的异常。
类似的,下面的编辑
.ForeignKey("dbo.Bugs", t => t.BugId) // Edited FROM 'ForeignKey("dbo.Bugs", t => t.Id)'
.ForeignKey("dbo.Doodles", t => t.DoodleId) // Edited FROM 'ForeignKey("dbo.Doodles", t => t.Id)'表示对于EF,DoodleId和BugId是而不是 FKs (相反,Id是),所以所有的行为和生成的SQL都将基于这一点。
尽管如此,不要手工编辑迁移以“修复”模型问题,而是修复模型。
在你的情况下,问题的根源是一对一的关系。默认情况下,EF对此类关系使用所谓的共享主键关联,其中依赖表的PK也是主体表的FK。当然,相依表的PK不再是身份。
怎么修呢?问题是,一对一的FK协会的支持有限。更具体地说,不支持显式FK属性。因此,您必须将它们从模型中删除,并且只保留导航属性:
public class DoodleBug
{
public int Id { get; set; }
public string Sentence { get; set; }
public DateTime Adate { get; set; }
public Boolean TrueFalse { get; set; }
public virtual Doodle Doodle { get; set; }
public virtual Bug Bug { get; set; }
}并按以下方式更改配置:
modelBuilder.Entity<DoodleBug>()
.HasRequired(db => db.Doodle)
.WithOptional(d => d.DoodleBUg)
.Map(c => c.MapKey("DoodleId"));
modelBuilder.Entity<DoodleBug>()
.HasRequired(db => db.Bug)
.WithOptional(b => b.DoodleBug)
.Map(c => c.MapKey("BugId"));现在,生成的迁移(w/o编辑!)是:
CreateTable(
"dbo.DoodleBug",
c => new
{
Id = c.Int(nullable: false, identity: true),
Sentence = c.String(),
Adate = c.DateTime(nullable: false),
TrueFalse = c.Boolean(nullable: false),
BugId = c.Int(nullable: false),
DoodleId = c.Int(nullable: false),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Bug", t => t.BugId)
.ForeignKey("dbo.Doodle", t => t.DoodleId)
.Index(t => t.BugId)
.Index(t => t.DoodleId);发布于 2019-07-01 17:09:35
我收到了这个错误。在我的例子中,在用脚手架创建MVC应用程序中的上下文之后,我更改了数据库上的列(设置标识)。所以我需要从DataContext类中删除这一行
entity.Property(e => e.Id).ValueGeneratedNever();这解决了我的问题!祝好运!
https://stackoverflow.com/questions/45652910
复制相似问题