如何在带有实体框架的SQL中使用自定义标识列

如何在带有实体框架的SQL中使用自定义标识列,sql,entity-framework,dbcontext,Sql,Entity Framework,Dbcontext,我正在尝试使用实体框架在表中使用自定义标识列。我拥有的是一个表,用于控制下一个可用于每个表的可用Id CREATE TABLE [dbo].[SystemNumbers]( [SystemNumberDesc] [varchar](30) NOT NULL, [LastId] [Int] NOT NULL CONSTRAINT [PK__SystemNumbers] PRIMARY KEY CLUSTERED ( [SystemNumberDesc] ASC )WIT

我正在尝试使用实体框架在表中使用自定义标识列。我拥有的是一个表,用于控制下一个可用于每个表的可用Id

CREATE TABLE [dbo].[SystemNumbers](
    [SystemNumberDesc] [varchar](30) NOT NULL,
    [LastId] [Int] NOT NULL
 CONSTRAINT [PK__SystemNumbers] PRIMARY KEY CLUSTERED 
(
    [SystemNumberDesc] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO
包含表的行计数器的行,插入方式如下

INSERT INTO SystemNumbers VALUES ('WS', 0)
  CREATE TRIGGER WSId 
    ON  WS     AFTER INSERT     
    AS   BEGIN   
  DECLARE @LastId INT  
  DECLARE @TableName VARCHAR(100)   
    DECLARE @INSERTID INT
    SET @TableName = 'WS'   
  SET NOCOUNT ON   
    SELECT @INSERTID = SystemID, @CREATETS = SystemTS, @StoreId = StoreId FROM Inserted 
  IF (@INSERTID = 0)   BEGIN  
      SELECT @LastId = LastId + 1 FROM SystemNumbers WHERE SystemNumberDesc = @TableName    
      UPDATE SystemNumbers SET LastId = @LastId WHERE SystemNumberDesc = @TableName          
      UPDATE WS SET SystemId = @LastId, WorkstationID=@LastId WHERE SystemId = @INSERTID 
  END 
  END  
然后创建要使用的表

CREATE TABLE [dbo].[WS](
    [WorkstationID]  INT NOT NULL,
    [WorkstationName] [varchar](50) NULL,
    [WSTS] TIMESTAMP,
 CONSTRAINT [PK_WS] PRIMARY KEY CLUSTERED 
(
    [WorkstationID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO
然后创建触发器,从
SystemCounters
表中获取下一个Id,并按如下方式更新Id

INSERT INTO SystemNumbers VALUES ('WS', 0)
  CREATE TRIGGER WSId 
    ON  WS     AFTER INSERT     
    AS   BEGIN   
  DECLARE @LastId INT  
  DECLARE @TableName VARCHAR(100)   
    DECLARE @INSERTID INT
    SET @TableName = 'WS'   
  SET NOCOUNT ON   
    SELECT @INSERTID = SystemID, @CREATETS = SystemTS, @StoreId = StoreId FROM Inserted 
  IF (@INSERTID = 0)   BEGIN  
      SELECT @LastId = LastId + 1 FROM SystemNumbers WHERE SystemNumberDesc = @TableName    
      UPDATE SystemNumbers SET LastId = @LastId WHERE SystemNumberDesc = @TableName          
      UPDATE WS SET SystemId = @LastId, WorkstationID=@LastId WHERE SystemId = @INSERTID 
  END 
  END  

使用SQL来执行插入操作,效果很好。然后,我将ADO.Net实体框架添加到我的项目中,并尝试插入一条记录

这给了我一个初始问题,即列定义为Computed,需要更改为Identity。我把这个换了,然后得到

EntityFramework.dll中发生类型为“System.Data.Entity.Infrastructure.DbUpdateConcurrencyException”的未处理异常

其他信息:Store update、insert或delete语句影响了意外的行数(0)。自加载实体后,实体可能已被修改或删除。刷新ObjectStateManager条目

我怀疑这是因为它插入了记录,然后试图重新加载它以获得诸如时间戳之类的Db值


我已经跟随了许多线索,但只是在一个圆圈结束。我需要从表中设置列,因为它是多存储的,因此标识字段将不起作用。

您的触发器有一个巨大的缺陷,您似乎认为每行调用一次触发器-SQL Server不是这种情况。如果
INSERT
UPDATE
影响多行,则每个语句将调用一次触发器,并且插入的
和删除的
伪表可以包含多行。因此,在执行
select@id1=i.id from inserted i时,您将选择这些行中的哪一行???它没有定义-您得到一行,任意行和所有其他行被忽略。。。。您需要重新写入触发器以处理插入的
和删除的
中的多行!我将在最终版本中考虑这一点,因为我在更新的WHERE子句中使用了一个Timestamp列。目前表是空的,我可以确信只有1条记录被插入。-干杯,马克,我不认为你能解决这个问题。一些替代方案:,没有什么可以解决的。查看代码,您试图基于表名生成一系列唯一的整数值。你也可以为这些表创建一个标识键,让系统为你做所有的工作。我需要生成Id,因为在某个阶段将有2个数据库合并在一起,所以当您合并数据时,Id开始创建间隙。作为其中的一部分,有一个DbId作为Id的前缀,以确保它是唯一的。