【问题标题】:How do I not violate this primary key when syncing with Azure?与 Azure 同步时如何不违反此主键?
【发布时间】:2015-08-01 13:10:48
【问题描述】:

项目总结

我们正在创建一个“数字”厨房,您可以在其中添加冰箱、冰柜等中的物品。然后可以在网络应用程序上查看这些物品,这样您就可以随时随地了解厨房里的杂货.

数据库

总共有三张桌子。

列表

这包含 ListID 和这些列表的名称,例如“冰箱”或“冰箱”。所以,这基本上就是“容器”。

项目

然后是 Items,其中包含 itemtypes,即 Milk,1 加仑。

列表项

然后是 ListItems(对不起,名称有点混乱),其中包含 特定 项。 Items 只是一个可以添加的项目表,ListItems添加 项。因此,添加到该表中的行自然具有 Lists 表上的 List 的外键和 Item 表上的 Item 的外键项目表。该表的主键是一个超级键,几乎由它的所有属性组成。

两个ListItem可以引用同一个Item和同一个List,只要它们有不同的属性即可。它们可能在不同的日期到期或具有不同的单位尺寸。唯一使 Item 独一无二的是名称,就像添加“Ham”一样,它永远不会覆盖“Milk”。添加另一个“牛奶”将被视为相同的 Item

问题

这是一个例子。您想添加两个单独的项目。第一个是 3 条火腿,每条 200 克,将于 5 月 28 日到期。 下一个是另一个火腿,这是一个单一的,但 500 克,将于 5 月 31 日到期:

ListID 1 指的是名为 Fridge 的 List。 ItemID 1 指的是名为 Ham 的项目。

看到问题了吗?外键相同。

它在我们的本地数据库中存储得很好,但是在与 Azure 数据库同步时,我们收到以下错误:

{"Violation of PRIMARY KEY constraint 'PK__#A4D1762__44A4C03D49E5E4B8'. 
Cannot insert duplicate key in object 'dbo.@changeTable'. 
The duplicate key value is (1, 1).\r\n
The data for table-valued parameter \"@changeTable\" doesn't conform to the table type of the parameter. 
SQL Server error is: 3602, state: 30\r\nThe statement has been terminated."}

这是糟糕的数据库设计还是 Azure 的问题?

更新 1

DDL 在本地数据库中的外观如下:

CREATE TABLE [dbo].[ListItems] (
    [ListId] INT NOT NULL,
    [ItemId] INT NOT NULL,
    [Amount] INT NOT NULL, 
    [Volume] INT NOT NULL, 
    [Unit] NVARCHAR(MAX) NULL, 
    [ShelfLife] DATETIME NOT NULL, 
    CONSTRAINT [pk_ListItems] PRIMARY KEY CLUSTERED ([ShelfLife], [Volume], [Amount], [ItemId], [ListId]),
    CONSTRAINT [fk_ListItems] FOREIGN KEY ([ListId]) REFERENCES [dbo].[Lists] ([ListId]) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT [fk_ListItems2] FOREIGN KEY ([ItemId]) REFERENCES [dbo].[Items] ([ItemId]) ON DELETE CASCADE ON UPDATE CASCADE
);

还有 Azure 数据库 DDL:

CREATE TABLE [dbo].[ListItems] (
    [ListId]    INT            NOT NULL,
    [ItemId]    INT            NOT NULL,
    [Amount]    INT            NOT NULL,
    [Volume]    INT            NOT NULL,
    [Unit]      NVARCHAR (MAX) NULL,
    [ShelfLife] DATETIME       NOT NULL,
    CONSTRAINT [PK_dbo.ListItems] PRIMARY KEY CLUSTERED ([ListId] ASC, [ItemId] ASC, [Amount] ASC, [Volume] ASC, [ShelfLife] ASC),
    CONSTRAINT [FK_dbo.ListItems_dbo.Items_ItemId] FOREIGN KEY ([ItemId]) REFERENCES [dbo].[Items] ([ItemId]) ON DELETE CASCADE,
    CONSTRAINT [FK_dbo.ListItems_dbo.Lists_ListId] FOREIGN KEY ([ListId]) REFERENCES [dbo].[Lists] ([ListId]) ON DELETE CASCADE
);

PK CONSTRAINT 行略有不同,但属性相同。会不会是这个问题?

【问题讨论】:

  • 在我看来,您的主键在 Azure 系统上设置不正确。如错误消息所述,重复键值为 (1,1),但您的主键还需要包含金额、体积、单位等。
  • 你提到它stores just fine on your local database,但是你不会有与 Azure db 相同的主键约束,否则它也会失败。你能分享一些本地和 Azure db 的 DDL 代码吗?
  • 也许您应该考虑在 ListItems 表中添加一些标识列并将其作为主键?那么,您当前的“超级键”可能只是一个唯一索引(以避免重复)。
  • 两者同步时是否会出现问题?传统的做法是在这里使用guid,这样key可以在任一数据库中生成,并保证在整个系统中是唯一的。
  • 我已经为两个 ListItem 表添加了 DDL 代码!

标签: c# sql sql-server database microsoft-sync-framework


【解决方案1】:

我认为错误不在您认为的位置。如果本地和 Azure ListItems 上的 PK 都命名相同的列(不考虑顺序),则它们是相同的。但是,错误消息提到了不同的 PK 定义(和不同的表名):

Violation of PRIMARY KEY constraint 'PK__#A4D1762__44A4C03D49E5E4B8'. Cannot insert duplicate key in object 'dbo.@changeTable'. The duplicate key value is (1, 1).

似乎有一个名为“@changetable”的表——对我来说它看起来像一个存储过程参数——它是用两列主键定义的。跟踪它,您将解决问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 2012-07-15
    相关资源
    最近更新 更多