不能为表&#39中的标识列插入显式值;当IDENTITY_INSERT设置为OFF时

当我执行下面的脚本时,我有以下错误。错误是关于什么,如何解决?

Insert table(OperationID,OpDescription,FilterID)
values (20,'Hierachy Update',1)

错误:

服务器:Msg 544,级别16,状态1,线路1

当IDENTITY_INSERT设置为OFF时,无法为表'table'中的标识列插入显式值。

1117688 次浏览

你正在为OperationId插入值,它是一个标识列。

您可以像这样在表上打开标识插入,以便您可以指定自己的标识值。

SET IDENTITY_INSERT Table1 ON


INSERT INTO Table1
/*Note the column list is REQUIRED here, not optional*/
(OperationID,
OpDescription,
FilterID)
VALUES      (20,
'Hierachy Update',
1)


SET IDENTITY_INSERT Table1 OFF

不要给OperationID赋值,因为它会自动生成。试试这个:

Insert table(OpDescription,FilterID) values ('Hierachy Update',1)

要非常小心地将IDENTITY_INSERT设置为ON。这是一种糟糕的实践,除非数据库处于维护模式并设置为单用户。这不仅会影响您的插入,还会影响试图访问表的其他人的插入。

为什么要在单位字段中输入一个值?

如果您正在使用liquibase更新SQL Server,则可能试图将记录键插入到autoIncrement字段中。通过从插入中删除列,脚本应该可以运行。

<changeSet id="CREATE_GROUP_TABLE" >
<createTable tableName="GROUP_D">
<column name="GROUP_ID" type="INTEGER" autoIncrement="true">
<constraints primaryKey="true"/>
</column>
</createTable>
</changeSet>


<changeSet id="INSERT_UNKNOWN_GROUP" >
<insert tableName="GROUP_D">


<column name="GROUP_ID" valueNumeric="-1"/>
...
</insert>
</changeSet>

如果你使用Oracle SQL Developer进行连接,记得添加/sqldev:支撑/

/sqldev:支撑/ set identity_insert TABLE on

另一种情况是检查主键是否为相同的名称,就像你的类一样,唯一的区别是你的主键有一个'ID'附加在它上面,或者在与类的命名方式无关的主键上指定[Key]。

在您的查询中有前面提到的OperationId,它不应该在那里,因为它是自动递增的

Insert table(OperationID,OpDescription,FilterID)
values (20,'Hierachy Update',1)

所以你的问题是

Insert table(OpDescription,FilterID)
values ('Hierachy Update',1)

在该表的实体中,将DatabaseGenerated属性添加到设置了身份插入的列之上:

例子:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TaskId { get; set; }

我不确定“插入表”的用途是什么,但如果你只是想插入一些值,请尝试:

Insert Into [tablename] (OpDescription,FilterID)
values ('Hierachy Update',1);

我有同样的错误消息出现,但我认为这应该工作。只要是主键,ID就应该自动递增。

如果你在SQL服务器上得到这个错误,然后运行这个查询-

SET IDENTITY_INSERT tableName ON

仅对数据库的单个表有效 例:如果表名是student,则查询如下:

SET IDENTITY_INSERT student ON

如果你在你的web应用程序或你使用实体框架得到这个错误,那么首先在SQL server上运行这个查询,更新你的实体模型(.edmx file)并构建你的项目,这个错误将被解决

如果您使用Interface并以通用方式实现savechanges方法,则会出现使用非类型化DBContext或DBSet的问题

如果这是您的情况,我建议使用强类型的dbcontext

MyDBContext.MyEntity.Add(mynewObject)

那么.Savechanges将工作

例如,如果你的表名是学校,你可以简单地使用这个语句。 插入前确保identity_insert设置为,插入查询后将identity_insert设置为

SET IDENTITY_INSERT School ON
/*
insert query
enter code here
*/
SET IDENTITY_INSERT School OFF

基本上有两种不同的方法来插入记录而不会出现错误:

1)当IDENTITY_INSERT设置为OFF时。主键“id”不能出现

2)当IDENTITY_INSERT设置为ON时。主键“id”必须出现

根据下面的例子,同一个表用IDENTITY主键创建:

CREATE TABLE [dbo].[Persons] (
ID INT IDENTITY(1,1) PRIMARY KEY,
LastName VARCHAR(40) NOT NULL,
FirstName VARCHAR(40)
);

1)在第一个例子中,当IDENTITY_INSERT是OFF时,你可以插入新的记录到表中而不会得到一个错误。INSERT INTO语句中的主键“id”不能出现如果在这种情况下,ID从INSERT中出现,您将得到错误“不能为表中标识列插入显式值…”

SET IDENTITY_INSERT [dbo].[Persons] OFF;
INSERT INTO [dbo].[Persons] (FirstName,LastName)
VALUES ('JANE','DOE');
INSERT INTO Persons (FirstName,LastName)
VALUES ('JOE','BROWN');

表[dbo]的输出。[人员]将是:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE

2)在第二个例子中,当IDENTITY_INSERT是ON的时候,你可以插入新的记录到表中而不会得到一个错误。只要ID值不存在:如果在这种情况下,ID没有从INSERT中出现,你将得到错误“必须为标识列表指定显式值…”

SET IDENTITY_INSERT [dbo].[Persons] ON;
INSERT INTO [dbo].[Persons] (ID,FirstName,LastName)
VALUES (5,'JOHN','WHITE');
INSERT INTO [dbo].[Persons] (ID,FirstName,LastName)
VALUES (3,'JACK','BLACK');

表[dbo]的输出。[人员]将是:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE
3     BLACK      JACK
5     WHITE      JOHN
  1. 这发生在你有一个(主键)列,没有设置为标识为真SQL和你没有在插入期间传递显式的值。它会取第一行,然后你不能插入第二行,错误会弹出。这可以通过在PrimaryKey列中添加这行代码[DatabaseGenerated(DatabaseGeneratedOption.Identity)]来纠正,并确保其设置为数据类型int。如果列是主键,并且在SQL中将IsIDentity设置为true,则不需要这行代码[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  2. 当你有一个不是主键的列时,这也会发生,在SQL中,它被设置为is Identity为true,并且在你的EF中,你没有添加这行代码[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

只需删除拖放到.dbml文件中的表,然后重新拖动它们。清洁方案>重建方案>重建方案。

这对我很管用。

我没有做我自己的表格,我是用VS和SSMS,我遵循这个链接为ASP。NET身份:https://learn.microsoft.com/en-us/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project

最好的解决方案是使用注释GeneratedValue(strategy = ...),即。

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column ...
private int OperationID;

它说,这个列是由数据库使用IDENTITY策略生成的,你不需要关心-数据库会做的。

如果你在使用带有sequize -typescript npm的sql-server时遇到这个问题,请确保将@AutoIncrement添加到ID列:

  @PrimaryKey
@AutoIncrement
@Column
id!: number;

我通过每次向数据库添加任何东西时创建一个新对象来解决这个问题。

请注意,如果你用;结束每一行,SET IDENTITY_INSERT mytable ON命令将不适用于以下行。

< p >。< br > 像

这样的查询
SET IDENTITY_INSERT mytable ON;
INSERT INTO mytable (VoucherID, name) VALUES (1, 'Cole');

给出错误
Cannot insert explicit value for identity column in table 'mytable' when IDENTITY_INSERT is set to OFF. < / p >

但是像这样的查询是可以的:

SET IDENTITY_INSERT mytable ON
INSERT INTO mytable (VoucherID, name) VALUES (1, 'Cole')
SET IDENTITY_INSERT mytable OFF;

似乎SET IDENTITY_INSERT命令只适用于事务,而;将表示事务的结束。

每个人都评论SQL,但在EntityFramework中发生了什么?我看了整篇文章,没人能解出EF。所以几天后,我找到了一个解决方案: 在EF Core上下文中创建模型有这样一条指令: modelBuilder.Entity<Cliente>(entity => { entity.Property(e => e.Id).ValueGeneratedNever();

这也会产生错误,解决方案:你必须通过ValueGeneratedOnAdd()改变它的工作!

在我的情况下,我插入了比表中定义的更多的字符。

在我的表列是用nvarchar(3)定义的,我正在传递超过3个字符和相同的ERROR消息。

这不是答案,但在某些情况下可能是类似的问题

在我的例子中,我已经在modelBuilder的上下文中设置了另一个属性作为键。

modelBuilder.Entity<MyTable>().HasKey(t => t.OtherProp);

我必须设置正确的id

 modelBuilder.Entity<MyTable>().HasKey(t => t.Id);

我使用asp.net core 5.0,我得到这个错误。我得到这个错误,因为我正在添加另一个数据并触发另一个.SaveChanges()方法,如下所示:

 _unitOfWorkVval.RepositoryVariantValue.Create(variantValue);
int request = HttpContext.Response.StatusCode;
if (request == 200)
{
int tryCatch = _unitOfWorkCVar.Complete();
if (tryCatch != 0)
{
productVariant.CategoryVariantID = variantValue.CategoryVariantID;
productVariant.ProductID = variantValue.ProductID;
productVariant.CreatedDate = DateTime.Now;
_unitOfWorkProductVariant.RepositoryProductVariant.Create(productVariant);
_unitOfWorkVval.RepositoryVariantValue.Create(variantValue);
int request2 = HttpContext.Response.StatusCode;
if(request==200)
{
int tryCatch2=_unitOfWorkProductVariant.Complete();//The point where i get that error
}///.......


使用实体框架与这样的模型有同样的问题(我简化了原始代码):

public class Pipeline
{
public Pipeline()
{
Runs = new HashSet<Run>();
}


public int Id {get; set;}
public ICollection<Run> Runs {get;set;}
}


public class Run
{
public int Id {get; set;}
public int RequestId {get; set;}
public Pipeline Pipeline {get;set;}
}

运行与管道有多对1的关系(一个管道可以运行多次)

在我的RunService中,我将dbcontext注入为context。DbContext有一个Runs DbSet。我在RunService中实现了这个方法:

public async Task<Run> CreateAndInit(int requestId, int pplId)
{
Pipeline pipeline = await pipelineService.Get(pplId).FirstOrDefaultAsync().ConfigureAwait(false);
Run newRun = new Run {RequestId = requestId, Pipeline = pipeline};
context.Runs.Add(newRun);
await context.SaveChangesAsync().ConfigureAwait(false); // got exception in this line
return newRun;
}

当方法执行时,我得到了这个异常:

Exception has occurred: CLR/Microsoft.EntityFrameworkCore.DbUpdateException
Exception thrown: 'Microsoft.EntityFrameworkCore.DbUpdateException' in System.Private.CoreLib.dll: 'An error occurred while updating the entries. See the inner exception for details.'
Inner exceptions found, see $exception in variables window for more details.
Innermost exception     Microsoft.Data.SqlClient.SqlException : Cannot insert explicit value for identity column in table 'Pipelines' when IDENTITY_INSERT is set to OFF.

对我来说,解决方案是将对象和关系的创建分开

public async Task<Run> CreateAndInit(int requestId, int pplId)
{
Pipeline pipeline = await pipelineService.Get(pplId).FirstOrDefaultAsync().ConfigureAwait(false);
Run newRun = new Run {RequestId = requestId};
context.Runs.Add(newRun);
newRun.Pipeline = pipeline; // set the relation separately
await context.SaveChangesAsync().ConfigureAwait(false); // no exception
return newRun;
}

EF Core 3.x

引用Leniel Maccaferri,我有一个带有自动递增属性的表,称为ID(原始主键)和另一个属性称为Other_ID(新的主键)。最初ID是主键,但后来Other_ID需要成为新的主键。由于ID正在应用程序的其他部分使用,我不能只是从表中删除它。Leniel Maccaferri解决方案只适用于我之后,我添加了以下片段:

        entity.HasKey(x => x.Other_ID);
entity.Property(x => x.ID).ValueGeneratedOnAdd();

完整代码片段如下(ApplicationDbContext.cs):

  protected override void OnModelCreating(ModelBuilder builder)
{
builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
base.OnModelCreating(builder);
builder.Entity<tablename>(entity =>
{
entity.HasKey(x => x.Other_ID);
entity.Property(x => x.ID).ValueGeneratedOnAdd();
entity.HasAlternateKey(x => new { x.Other_ID, x.ID });
});
        

}
  1. 首先转到所需的表名

步骤2 ->右键单击表名

第三步——>选择设计

第四步——>单击列名

步骤5)进入列属性,然后将没有设置为标识规范

[注意:插入到显式值后,如果你想,你可以返回到标识规范为true,然后它将再次生成值]

如果你使用SQL server管理studio你可以使用下面的方法

< p >步骤1) enter image description here 2) enter image description here

即使一切正确,如果Identity列的数据类型不是int或long,也会出现此错误。我有单位列为十进制,虽然我只保存int值(我的坏)。更改数据库和底层模型中的数据类型为我解决了这个问题。

把断点放在你的[HttpPost]方法上,检查什么值被传递给Id属性。如果它不为零,则会发生此错误。

首先…

首先,您需要知道为什么会出现错误。

让我们以一个简单的JSON数据HttpPost为例,如下所示:

{
"conversationID": 1,
"senderUserID": 1,
"receiverUserID": 2,
"message": "I fell for the wrong man!",
"created":"2022-02-14T21:18:11.186Z"
}

如果你在连接到SQLServer或任何其他数据库服务器时使用Entity框架核心生成数据库,数据库将自动负责更新和自动生成标识列的Key/Unique标识符,在大多数情况下,这是一个由它自动递增的整数值。

为了使用内置的约定安全地发布数据,可以将ID字段从想要发送到数据库的数据中删除,并让数据库引擎和ef-core完成它们设计的繁重工作。

所以发布数据的正确方式是:

{
"senderUserID": 1,
"receiverUserID": 2,
"message": "I fell for the wrong man!",
"created":"2022-02-14T21:18:11.186Z"
}

你会注意到我拿出了ConversationID。

你可以在这个网站上了解更多关于实体框架的信息:https://entityframeworkcore.com

我希望您在应用程序中更多地遵循约定,而不是配置。知道如何按照已经被证实的标准和惯例做事将为您节省大量的工作时间。