Microsoft Sync Framework 唯一索引错误
Microsoft Sync Framework unique index error
我使用 MS Sync Framework 将我的 SQL 服务器实例与本地 SQL CE 文件同步,以便可以离线使用我的 Windows 应用程序。
我使用 GUID 作为键。在我的 table 上,我在 2 列上有一个 唯一索引 :user_id
和 setting_id
:
usersettings table
------------------
id PK -> I also tried it without this column. Same result
user_id FK
setting_id FK
value
现在我执行以下操作:
我在 table 这两个数据库中创建了一条新记录 - SQL 服务器和 SQL CE 具有相同的 user_id
和 setting_id
。
这应该可行并将数据合并在一起,因为这在现实生活中可能会发生。但是在同步时出现错误,说唯一键约束导致错误。 table.
中已存在密钥对
A duplicate value cannot be inserted into a unique index. [ Table name = user_settings,Constraint name = unique_userid_settingid ]
为什么 MS 同步无法处理?它不应再次尝试插入密钥对。如果需要,它应该更新值。
问题是,如果您将相同的密钥对添加到 table 的不同副本,它们将获得不同的 ID (GUID) 作为此用户设置中的主键 table。
因为这只是用户和设置之间的 many-to-many table,所以不需要将该 ID 作为 PK(甚至根本不需要列)。
相反,只需使用两个 FK 的串联键,例如,
CREATE TABLE [dbo].[usersettings](
[user_id] [UNIQUEIDENTIFIER] NOT NULL,
[setting_id] [UNIQUEIDENTIFIER] NOT NULL,
[value] [varchar](50) NOT NULL,
CONSTRAINT [PK_usersettings] PRIMARY KEY CLUSTERED ([user_id] ASC, [setting_id] ASC) );
当然,包括适当的字段设置(例如,如果您使用 VARCHAR 来存储 ID)和相关的 FK。
由于现在插入的行在两个副本上应该是相同的,因此应该可以很好地合并。
如果您必须有一个列作为 table 的唯一标识符,您可以使其有意义,例如,
- PK(ID)变成varchar(72)
- 它充满了
CONCAT(user_ID, setting_id)
由于 User_ID 和 Setting_ID 是 FK,您应该已经生成了它们,因此连接它们应该很容易。
同步的时候有没有报错,那么应该表现为冲突,必须在代码中解决。
我在手册中也看到了这一点:默认情况下,以下对象不会复制到客户端数据库:FOREIGN KEY 约束、UNIQUE 约束、DEFAULT 约束和 SQL 服务器 ROWGUIDCOL 属性.这表明对您的场景的支持不佳
我建议您从设备 table 中删除唯一约束。
我使用 MS Sync Framework 将我的 SQL 服务器实例与本地 SQL CE 文件同步,以便可以离线使用我的 Windows 应用程序。
我使用 GUID 作为键。在我的 table 上,我在 2 列上有一个 唯一索引 :user_id
和 setting_id
:
usersettings table
------------------
id PK -> I also tried it without this column. Same result
user_id FK
setting_id FK
value
现在我执行以下操作:
我在 table 这两个数据库中创建了一条新记录 - SQL 服务器和 SQL CE 具有相同的 user_id
和 setting_id
。
这应该可行并将数据合并在一起,因为这在现实生活中可能会发生。但是在同步时出现错误,说唯一键约束导致错误。 table.
中已存在密钥对A duplicate value cannot be inserted into a unique index. [ Table name = user_settings,Constraint name = unique_userid_settingid ]
为什么 MS 同步无法处理?它不应再次尝试插入密钥对。如果需要,它应该更新值。
问题是,如果您将相同的密钥对添加到 table 的不同副本,它们将获得不同的 ID (GUID) 作为此用户设置中的主键 table。
因为这只是用户和设置之间的 many-to-many table,所以不需要将该 ID 作为 PK(甚至根本不需要列)。
相反,只需使用两个 FK 的串联键,例如,
CREATE TABLE [dbo].[usersettings](
[user_id] [UNIQUEIDENTIFIER] NOT NULL,
[setting_id] [UNIQUEIDENTIFIER] NOT NULL,
[value] [varchar](50) NOT NULL,
CONSTRAINT [PK_usersettings] PRIMARY KEY CLUSTERED ([user_id] ASC, [setting_id] ASC) );
当然,包括适当的字段设置(例如,如果您使用 VARCHAR 来存储 ID)和相关的 FK。
由于现在插入的行在两个副本上应该是相同的,因此应该可以很好地合并。
如果您必须有一个列作为 table 的唯一标识符,您可以使其有意义,例如,
- PK(ID)变成varchar(72)
- 它充满了
CONCAT(user_ID, setting_id)
由于 User_ID 和 Setting_ID 是 FK,您应该已经生成了它们,因此连接它们应该很容易。
同步的时候有没有报错,那么应该表现为冲突,必须在代码中解决。
我在手册中也看到了这一点:默认情况下,以下对象不会复制到客户端数据库:FOREIGN KEY 约束、UNIQUE 约束、DEFAULT 约束和 SQL 服务器 ROWGUIDCOL 属性.这表明对您的场景的支持不佳
我建议您从设备 table 中删除唯一约束。