【问题标题】:How to use default NEWID()/NEWSEQUENTIALID() with Guid/uniqueidentifier?如何将默认 NEWID()/NEWSEQUENTIALID() 与 Guid/uniqueidentifier 一起使用?
【发布时间】:2017-10-17 11:11:54
【问题描述】:

我有这张桌子:

CREATE TABLE [dbo].[SandTable](
    [Id]   [uniqueidentifier]  NOT NULL,
    [Date] [date]              NULL,
    CONSTRAINT [PK_SandTable] PRIMARY KEY)

ALTER TABLE [dbo].[SandTable] ADD  CONSTRAINT [DF_SandTable_Id]  DEFAULT (NEWID()) FOR [Id]

问题不在于使用 NEWID() 与 NEWSEQUENTIALID()。

我使用 linqPad 来测试表格。

SandTables.InsertOnSubmit(new SandTable
{
    // I don't provide any value for Id
    Date = DateTime.Now
});
SubmitChanges();

我最初的想法是创建一个 Id 列,该列能够在没有提供 Id 时将自身初始化为一个值,但在提供 ID 时将使用提供的 id。

但是因为 Guid 是一个结构,而不是一个 Id 永远不会为空的类,所以 Id 被初始化为他的默认值 (00000000-0000-0000-0000-000000000000)。所以 SQL server 认为 Id 总是有一个值,然后 NEWID() 默认指令永远不会被调用。

是否可以在特定值上强制调用 NEWID()?我是否应该使用触发器来评估 Id 的值以及何时为 (00000000-0000-0000-0000-000000000000) 然后调用 NEWID()?有什么解决方案或解决方法?

【问题讨论】:

  • 这里有一个类似的问题,有趣但没有回答我的具体问题:stackoverflow.com/q/11974939/196526
  • 也许是个愚蠢的问题,但如果您知道要插入 - 为什么不在代码中使用 id=Guid.NewGuid() 创建 GUID?因为你希望 SQL 来创建它?
  • 也是使用存储过程进行插入的一个选项吗?然后你可以检查 guid 是否为空,如果是则生成一个新的并执行插入。
  • 出于兼容性原因,因为我处于迁移应用程序的情况。旧应用程序从非优化的存储过程中插入新数据。我不能告诉你我们有多少版本的 INSERT。新应用程序使用 C# 代码。所以新应用程序可以创建一个 Guid 但我不能修改所有旧查询。
  • 我在 C# 代码中使用实体框架。我宁愿避免使用存储过程。出于维护原因,我想将所有逻辑保留在 C# 中。 (我也根本不信任我的 DBA 团队)

标签: c# sql-server entity-framework-6 guid


【解决方案1】:

您可以使用检查约束来做到这一点:

ALTER TABLE [dbo].[SandTable] 
    ADD CONSTRAINT [DF_SandTable_Id] DEFAULT (NEWID()) FOR [Id]

ALTER TABLE [dbo].[SandTable] 
    WITH CHECK ADD CONSTRAINT [CK_SandTable_Id_Empty] 
    CHECK (
        [Id] <> CAST(0x0 AS UNIQUEIDENTIFIER)
    )

【讨论】:

  • 我相信,检查约束用于验证传入的输入。您能否详细说明这一行:[Id] &lt;&gt; CAST(0x0 AS UNIQUEIDENTIFIER)
  • 这会阻止插入,我相信他希望它只生成 NewID() 如果传入的 id 是 0x0(我可能是错的)。
  • 我误解了这个问题。我很快就会更新一个新的答案。
  • 我用 LinqPad 确认我插入第一行它可以工作。我得到默认 ID,然后对于下一次插入,我得到经典的“SqlException:违反主键约束 'PK_SandTable'。无法在对象 'dbo.SandTable' 中插入重复键。语句已终止。”逻辑。
  • 我认为您无法使用约束或默认值来执行此操作。触发器是您唯一的选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-29
  • 2017-03-08
  • 1970-01-01
  • 1970-01-01
  • 2011-10-20
  • 1970-01-01
相关资源
最近更新 更多