首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在未提交Id时,接收"SqlException:无法在表‘’当IDENTITY_INSERT设置为OFF“中插入标识列的显式值

在未提交Id时,接收"SqlException:无法在表‘’当IDENTITY_INSERT设置为OFF“中插入标识列的显式值
EN

Stack Overflow用户
提问于 2017-08-12 17:14:01
回答 2查看 888关注 0票数 1

我使用的是ASP.Net MVC 5和EF6

我有一个叫DoodleBug的模型(不要问)。当我尝试创建这个实体的一个新条目并将其保存到数据库中时,我会得到以下异常,即使我没有输入Id值?

代码语言:javascript
复制
SqlException: Cannot insert explicit value for identity column in table 
'DoodleBugs' when IDENTITY_INSERT is set to OFF.

这是我的模型

代码语言:javascript
复制
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; }


}

这是控制器

代码语言:javascript
复制
// 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);
    }

这是一幅风景

代码语言:javascript
复制
<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实体和另外两个实体(DoodleBug)之间创建一个外键关系。

代码语言:javascript
复制
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);                                   // Added

NB控制器和视图是由EF搭建的,EF为create()方法中的ID添加了一个SelectList属性,在控制器ViewBag中为Id添加了一个项的SelectList,以及视图中的一个表单控件来使用控制器中的SelectList创建一个下拉列表选项,以输入Id值。

我删除了控制器Create()方法中的Bind属性中的Id,并注释掉了视图中与Id值相关的表单控件(如视图中第5-11行中的@* - *@所示)。

尽管如此,当我运行代码并尝试提交表单时,我得到了上面的错误吗?

当我在调试模式下运行应用程序时,doodleBug变量的属性框的Id值为0 (Int)。我不知道这是从哪里来的,还是它是一个默认值?

在回答下面的问题时,是涂鸦和Bug模型

代码语言:javascript
复制
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实体是两者的可选实体。

代码语言:javascript
复制
        // 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;

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-13 01:41:07

正如我在注释中提到的,您必须手动修改生成的迁移,这表明模型中存在问题。

例如,此编辑

代码语言:javascript
复制
Id = c.Int(nullable: false, identity: true), // Edited FROM 'Id = c.Int(nullable: false)'

迁移是基于该模型生成的。这里需要注意的是,从EF的角度来看,Id字段是而不是标识。虽然您的编辑固定了数据库字段,但对于EF,该字段仍然是而不是标识,因此EF不将其视为标识和相关行为,比如在执行INSERT时不传递值,而是像常规int字段一样将其值(在默认情况下为0)传递给INSERT命令,从而导致正在获得的异常。

类似的,下面的编辑

代码语言:javascript
复制
.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,DoodleIdBugId而不是 FKs (相反,Id是),所以所有的行为和生成的SQL都将基于这一点。

尽管如此,不要手工编辑迁移以“修复”模型问题,而是修复模型。

在你的情况下,问题的根源是一对一的关系。默认情况下,EF对此类关系使用所谓的共享主键关联,其中依赖表的PK也是主体表的FK。当然,相依表的PK不再是身份。

怎么修呢?问题是,一对一的FK协会的支持有限。更具体地说,不支持显式FK属性。因此,您必须将它们从模型中删除,并且只保留导航属性:

代码语言:javascript
复制
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; }
}

并按以下方式更改配置:

代码语言:javascript
复制
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编辑!)是:

代码语言:javascript
复制
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);
票数 0
EN

Stack Overflow用户

发布于 2019-07-01 17:09:35

我收到了这个错误。在我的例子中,在用脚手架创建MVC应用程序中的上下文之后,我更改了数据库上的列(设置标识)。所以我需要从DataContext类中删除这一行

代码语言:javascript
复制
 entity.Property(e => e.Id).ValueGeneratedNever();

这解决了我的问题!祝好运!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45652910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档