我们目前正在将旧的 OR 映射器迁移到 EF Core。直到现在我们使用 http://www.castleproject.org/projects/activerecord 或使用 HiLo 算法的映射器。解释是: https://github.com/castleproject-deprecated/ActiveRecord/blob/master/docs/primary-key-mapping.md
现在我们要切换到 EF Core 并尝试使用相同的算法。但是没有太多解释 HiLo 算法在 Nhibernate/ActiveRecord 中是如何工作的。我尽量避免 Id 冲突。
据我所知,Hi 值是在一个数据库中配置的: 从 hibernate_unique_key 中选择 next_hi 值:746708 我认为 maxLow 值是 Int16.MaxValue
在这种情况下,EFCore 的序列应该是:
CREATE SEQUENCE [dbo].[DBSequenceHiLo]
AS [bigint]
START WITH (select next_hi from hibernate_unique_key + Int16.MaxValue)
INCREMENT BY Int16.MaxValue
MINVALUE -9223372036854775808
MAXVALUE 9223372036854775807
CACHE
GO
ActiveRecord HiLo 算法究竟是如何工作的?什么是增量值?价值的起点是什么?迁移需要一些时间,是否可以与相同的 HiLo 算法并行运行?
答案 0 :(得分:0)
据我所知。不可能对 ActiveRecord 和 EF Core 使用完全相同的算法。一个使用 Sequence ,另一个使用表格。所以你不能同时使用 OR Mapper。但是你可以为EF Core创建一个没有ID冲突的序列,之后你就不能使用ActiveRecord了。
要获取 INCREMENT BY 值,只需启动当前应用程序。使用应用程序创建数据库条目。停下来。再次启动并创建第二个条目。因为您停止了应用程序,所以 Lo/cache 是空的,它会获得下一个 hi 值。这两个 ID 之间的区别是 Active Record 的“INCREMENT BY”值。就我而言,它是 2^17。我认为默认值应该是 2^15,但我还没有看到任何关于它的信息。
为了获得起始值,我创建了一个 SQL 脚本,以获取数据库的最高 Id。这是我的脚本(仅当您的 PK 名为 Id 并且仅适用于 sql 时才有效。)
DECLARE @tables TABLE(tablename nvarchar(max) NOT NULL);
DECLARE @name nvarchar(max)
DECLARE @maxid bigint
DECLARE @currentid bigint
DECLARE @query nvarchar(max);
DECLARE @sSQL nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);
set @maxid = 0
insert into @tables
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_CATALOG = 'BB_Vision'
While(Select Count(*) From @tables) > 0
Begin
Select Top 1 @name = tablename From @tables
IF EXISTS(SELECT 1 FROM sys.columns
WHERE Name = N'Id'
AND Object_ID = Object_ID(@name))
BEGIN
SELECT @sSQL = N'SELECT @retvalOUT = MAX(ID) FROM ' + @name;
SET @ParmDefinition = N'@retvalOUT bigint OUTPUT';
EXEC sp_executesql @sSQL, @ParmDefinition, @retvalOUT=@currentid OUTPUT;
IF @currentid > @maxid
BEGIN
set @maxid = @currentid
END
END
Delete @tables Where @name = tablename
End
select @maxid+1
现在您可以创建您的 EF Core 序列。以下是如何使用它的说明: https://www.talkingdotnet.com/use-hilo-to-generate-keys-with-entity-framework-core/
之后您不应再使用 ActiveRecord,否则您必须使用更高的起始值重新创建序列。
由于迁移需要一些时间,而且您仍将主要为当前 OR 映射器创建一些功能/错误修复,因此最好在本地数据库上将 ActiveRecord Hi 值设置为更大的值。因此,您可以在同一个数据库上使用两者。但我不会在生产中使用它
update hibernate_unique_key set next_hi = next_hi + next_hi