我目前正在开发一个带有 SQL Server 2000 数据库的旧 ASP 应用程序,我们正在尝试使用 .NET 和NHibernate将其移植到更新的技术。
在该数据库中,所有表都有一个复合 ID,如下所示:
CREATE TABLE [Languages](
[languageIncId] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[languageSqlId] [smallint] NOT NULL,
...
[createdByIncId] [int] NOT NULL,
[createdBySqlId] [smallint] NOT NULL,
...
[lastModifiedByIncId] [int] NULL,
[lastModifiedBySqlId] [smallint] NULL,
[rowguid] [uniqueidentifier] ROWGUIDCOL NOT NULL,
...
CONSTRAINT [PK_Languages] PRIMARY KEY CLUSTERED
(
[languageIncId] ASC,
[languageSqlId] 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
也就是说,每个表的主键由:
- XXXSqlId,它是创建项目的 SQL Server 实例的 ID
- XXXIncId,这是一个
IDENTITY
在插入新行时递增的字段
关键SqlId
在于,当复制发生时,记录会从一个数据库移动到另一个数据库,并且XXXIncId
可能会发生重复。不幸的是,没有更改数据库模式,因为很多应用程序都依赖它(这确实很痛苦)。
这也意味着每当表之间存在关系时,都需要提供两个字段,如createdByIncId , createdBySqlId
.
我正在寻找用 NHibernate(流利与否)映射此结构的最佳方法,但我被阻止了。我考虑了以下解决方案:
- 使用带有 SqlId 和 IncId 的Composite-ID(最自然的解决方案)但它不起作用,因为 IncId 是由数据库生成的,并且 CompositeID 不支持“生成”属性
- 完全忽略这些字段并将“rowguid”视为真实 ID:只要我不尝试处理实体之间的关系,这也很有效,它也应该使用“复合 ID”作为链接......
- 使用自定义复合用户类型(
ICompositeUserType
) :但这不能用作实体的 ID。
我的问题与问题1615647非常相似,但答案对我来说并不令人满意。
有什么想法可以跟进吗?