【问题标题】:How do i prevent Linq from adding a GUID so that SQL server can do it?我如何防止 Linq 添加 GUID 以便 SQL 服务器可以做到这一点?
【发布时间】:2012-04-02 06:29:24
【问题描述】:

我正在以编程方式创建和填充 LINQ to SQL 对象,然后将它们添加到带有唯一标识符列的 sql 服务器数据库中以用于 PK。 LINQ 会自动分配一个全 0 的 PK。这会在插入时产生错误,因为 PK 是重复的。

Dim myNewRecord as IceCreamTrackerTable
myNewRecord.name=Bob
myNewRecord.favoriteIceCream=Vanilla
   'myNewRecord.PK=00000000-0000-0000-0000-000000000000 (by default)'
myDataContext.IceCreamTrackerTables.insertOnSubmit(myNewRecord)
    ''second record added throws an error because it also has PK 00000 etc. 
  1. 我知道我可以使用 myNewRecord.pk=Guid.newGuid() 分配 PK Guid is all 0's (zeros)?
  2. 但我真正想要的是让 SQL Server 分配 GUID,因为我假设它有一些方法来确保它不会重新分配相同的 guid

有什么方法可以告诉 LINQ 我不想自己填写 GUID 而是让 SQL Server 来处理?

【问题讨论】:

    标签: .net sql-server linq


    【解决方案1】:

    Guid 是值类型,因此它们不能为空。这意味着当创建 Guid 时,它必须分配一个默认值(全为 0)。 SQL Server 不会像为标识列那样自动为主键生成 GUID。您可以将默认值设置为 NEWID(),但默认情况下 EF 会忽略它并尝试插入一个值。您可以通过执行此处描述的操作来覆盖它

    http://softmindit.blogspot.com/p/using-guid-as-entitykey-in-entity.html

    编辑:我刚刚意识到您使用的是 Linq to sql 而不是 Linq to entity。不过,我确信 L2S 中也有类似的东西可以处理这个问题。

    Edit2:在 linq to sql 中也有类似的东西,如截图所示。更改此属性可解决问题

    【讨论】:

      【解决方案2】:

      您可以注释您的 GUID 列以表明它是使用 IsDbGenerated 生成的 DB:

      [Column(Storage="_PK", 
              AutoSync=AutoSync.OnInsert, 
              DbType="UniqueIdentifier NOT NULL", 
              IsPrimaryKey=true, IsDbGenerated=true)]
      public Guid PK
      {
        //...
      }
      

      【讨论】:

        【解决方案3】:

        我假设它有一些方法可以确保它不是 重新分配相同的 guid

        Guids 的全部意义在于它们是独一无二的……或者至少通常是独一无二的。如果它们都是从同一个来源分配的,例如在您的服务器上调用 Guid.NewGuid(),那么您肯定不会遇到任何冲突。

        【讨论】:

        • 谢谢。我担心的是 SQL 服务器上的 GUID 和 Visual Studio 中的 GUID 没有“说话”。因此,有两个独立的 guid 制造商,每个都分配 guid。我宁愿只有一个实体负责制作向导。 Visual Studio 的 Guid 制作方法是否考虑了数据库中已经存在的 guid?这对我来说似乎不太可能。我错过了什么吗?
        • 不,它不考虑它,但它没有必要。无论是谁生成,无论多快,无论是什么平台或软件,理论上都不可能得到重复的 GUID。
        • @akh2103 - 在特定机器上生成的任何 Guid 最终解析为调用相同的底层方法,无论是从 Visual Studio 应用程序、SQL Server 中的函数调用还是第三方应用程序调用.我不知道评估的细节,但我怀疑它是当前计时器和其中的 MAC 地址。同样,通常是独一无二的,但不能保证 100.00000% 如此。但是,如果它们都是从同一来源生成的,那么您就极不可能遇到冲突。
        • GUID 生成器不会验证您的表中不存在 GUID 值。它怎么知道它要去哪里? SQL 中的 GUID 生成器也不会进行此验证,并且可能会在操作系统中调用相同的生成器。简短的故事是:不要让您担心,两次生成相同 GUID 的机会非常小。
        【解决方案4】:

        这里的问题是,由于您的 PK 是一个值类型,它总是有一些值(没有 null 的等价物)。因此,除非生成的类包含特定的功能来跟踪您是否“手动”设置了值并在没有设置值的情况下省略它,否则没有办法做到这一点。

        因此,查看IceCreamTrackerTable 的来源将提供明确的答案。

        【讨论】:

        • 啊!我从 LINQ to sql IceCreamTrackerTable 对象中删除了 PK,现在尝试提交时出现此错误:Can't perform Create, Update, or Delete operations on 'Table(IceCreamTrackerTable)' because it has no primary key.
        猜你喜欢
        • 1970-01-01
        • 2016-06-24
        • 1970-01-01
        • 2011-01-30
        • 1970-01-01
        • 1970-01-01
        • 2017-11-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多