更新 : 2019-06-29
identity column 的局限是, 它只可以在一个 table 使用,而且它只能随着 insert 产生
另一个方法是用 SEQUENCE, sql server 2012 的功能
https://docs.microsoft.com/en-us/ef/core/modeling/relational/sequences
https://www.talkingdotnet.com/use-sql-server-sequence-in-entity-framework-core-primary-key/
https://blog.csdn.net/m0_38002798/article/details/78904102
它的好处是可以跨 table, 而且不需要 insert 也可能产生. 但是也有不足的地方,就是不支持 transaction , 无法 rollback
如果你的 running number 允许跳号, 那么 SEQUENCE 是最佳选择.
如果以上 2 个无法满足需求,那么就得自己通过表,锁表的方式去实现了.
有时候我们希望 Id 要好看一些,比如 Id=1 -> Id=T000001
refer :
http://www.kodyaz.com/t-sql/custom-sequence-string-as-sql-identity-column.aspx
http://www.sqlteam.com/article/custom-auto-generated-sequences-with-sql-server
方法有很多,我目前选择的方式是使用触发器在插入之后更新
我们把这个好看一点的Id称为 viewId 吧。
先做一个方法来格式化Id
调用 viewId = dbo.getViewId('T',CAST(inserted.Id as nvarchar(50)),6,'0');
drop function dbo.getViewId; create function [dbo].[getViewId] ( @Prefix nvarchar(10), @Id int, @Length int, @PaddingChar char(1) = '0' ) returns nvarchar(MAX) as begin return ( select @Prefix + RIGHT(REPLICATE(@PaddingChar, @Length) + CAST(@Id as nvarchar(10)), @Length) ) end
针对某个表写入触发器逻辑
drop trigger OrdersAfterInsert; create trigger OrdersAfterInsert on [dbo].[Orders] for insert as update Orders set viewId = dbo.getViewId('O', CAST(inserted.Id as nvarchar(50)),6,'0') from Orders inner join inserted on Orders.Id= inserted.Id; go
如果表已经存在数据的话,要更新哦
update Orders set viewId = dbo.getViewId('O', CAST(Id as nvarchar(50)),6,'0');
创建column and UNIQUE
alter table Orders add viewId nvarchar(50) null; create unique nonclustered index [UNIQUE_Orders_viewId] on [dbo].[Orders]([viewId] asc) where ([viewId] IS NOT NULL AND [viewId] IS NOT NULL);
使用 Entity Framewrok的话可以把这个数据标签为 Computed.
public class Order { [Key] public int Id { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public string viewId { get; set; } }
以上.