“当IDENTITY_INSERT设置为OFF”时,无法使用复合键为表中的标识列插入显式值

问题描述 投票:12回答:10

我们最近在数据库中添加了一个新的“级别” - 在整个数据库的表中的现有ID Identity字段之上/之前添加了一个键“Company_ID”。

例如,如果表具有ID然后是字段,则它现在具有Company_ID,然后是ID,然后是字段。这个想法是,这允许ID为提供给功能的每个不同的Company_ID值自动递增(Company_ID 1可以具有ID 1,2,3等; Company_ID 2可以具有ID 1,2,3等)。

自动增量字段保持为IS。示例表是:

    [dbo].[Project](
      [Company_ID] [int] NOT NULL,
      [ID] [int] IDENTITY(1,1) NOT NULL,
      [DescShort] [varchar](100) NULL,
      [TypeLookUp_ID] [int] NULL,
      [StatusLookUp_ID] [int] NULL,
      [IsActive] [bit] NOT NULL,
    CONSTRAINT [PK_Project] PRIMARY KEY CLUSTERED 
    (
      [Company_ID] ASC,
      [ID] ASC
    )

在引入Company_ID之前,为了执行CREATE,我们只需填充DescShort,TypeLookUp_ID,StatusLookUp_ID和IsActive字段,并将ID保留为默认值,可能为0。

记录已成功保存,ID由数据库自动填充,然后用于通过View执行SHOW,依此类推。

但是,现在我们要将Company_ID设置为指定值,保留ID,并像以前一样填充字段。

    _db.Project.Add(newProject);
    _db.SaveChanges();

是的,我们要指定Company_ID值。我们希望自动填充ID,如前所述。我们收到错误消息:

当IDENTITY_INSERT设置为OFF时,无法在表“Project”中为identity列插入显式值

这是由指定Company_ID还是ID字段引起的?你知道我们如何纠正这个问题吗?

c# sql sql-server-2008 composite-primary-key
10个回答
14
投票

问题在于ID。如果将字段设置为IDENTITY,则通常无法为其分配值 - IDENTITY属性将其标记为允许数据库自动为列指定递增值。

要解决此问题,请从ID中删除自动IDENTITY属性(如果要自动递增它,您可以在处理代码中始终执行此操作 - 在字段中获取最高值,向其中添加一个,然后分配该值)或转到数据库并在表上设置IDENTITY _INSERT,这暂时允许您为IDENTITY字段分配值。

SET IDENTITY_INSERT [yourTableName] ON

--go back and run your C# code>

SET IDENTITY_INSERT [yourTableName] OFF

-2
投票

如果您的表中有自动增量字段,请查看。将自动增量设置为NO,然后执行SQL。在该字段中重新放入自动增量并再次同步之后。


11
投票

睡觉后,我发现了这个,对于Visual Studio c#代码:[DatabaseGenerated(DatabaseGeneratedOption.Identity)]。这个(在我看来),为我的每个ID字段定义,告诉Visual Studio该字段是一个标识,并在向数据库发送值时“不管它”。当Company_ID首先出现并且有一个值时,告诉Visual Studio其他地方有一个Identity字段允许_db.Project.Add(newProject);然后_db.SaveChanges();按要求运行。这部分答案是针对Visual Studio方面的。我理解IDENTIY_INSERT的SQL要求,所以感谢@ matt-thrower,@ steve-pettifer和其他贡献者。


5
投票

对我有用的是simple EDMX update。因为我之前设置了身份关闭,然后将其更改为自动。但没有更新Edmx。更新后,它工作正常。


3
投票

在这个例子中对我有用的是在类中的主键属性上设置一个属性:

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int DepartmentId { get; set; }

IDENTITY_INSERT已在我的数据库中。


0
投票

你可以尝试两件事并分别尝试吗?

  • 删除ID和Company_ID的主键字段
  • 在第一个订单上取ID列

0
投票

从Id中删除标识或添加

SET IDENTITY_INSERT [dbo].[Project] ON

通常插入ID时不会受到用户干扰,因此您会收到错误,因为您正在尝试在其中输入数据。设置它将允许您输入您想要的数据或者,简单地将您输入数据的代码删除到ID中,除非这是您需要的东西


0
投票

好的,您已经有了解决方案......但考虑将ID保留为唯一主键,将Company_Id保留为外键


0
投票

SQL表中外键的增量是自动设置...所以当你想插入任何东西时,你必须从像这样的代码中删除这个外键。

Sql代码:

CREATE TABLE [dbo].[annexe1](
[cle] [int] IDENTITY(1,1) NOT NULL,
[tarif] [nvarchar](50) NULL,
[libele] [nvarchar](max) NULL)

Asp.Net代码:

InsertCommand = "INSERT INTO [annexe6] ([cle], [tarif], [libele]) VALUES (@cle, @tarif, @libele)"

更正:

InsertCommand = "INSERT INTO [annexe6] ([tarif], [libele]) VALUES (@tarif, @libele)"

0
投票

您的ID必须是唯一的。为此使用一些哈希。 (例如GUID)

[Key]
public string Id { get; set; }

public your_constructor()
{
    Id = Guid.NewGuid().ToString();
}
© www.soinside.com 2019 - 2024. All rights reserved.