如何在实体框架中为GUID设置NewId()

use*_*613 12 asp.net-mvc asp.net-mvc-3 asp.net-mvc-4 entity-framework-5

我正在创建asp.net mvc4示例.在此我在datacontext的Sample表中创建了Id列作为GUID.

public class Sample
{
    [Required]
    public Guid ID { get; set; }
    [Required]
    public string FirstName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这是实体表

CreateTable(
"dbo.Samples",
 c => new
 {
     ID = c.Guid(nullable: false),
     FirstName = c.String(nullable: false)                   
 })
 .PrimaryKey(t => t.ID);
Run Code Online (Sandbox Code Playgroud)

Id传递00000000-0000-0000-0000-000000000000.

如何设置newid()GUID哪里我必须设置.

Pau*_*aul 13

我建议只使用long你的ID类型.它"正常工作"并且比GUID有一些性能提升.但是,如果要使用GUID,则应使用顺序GUID并在构造函数中进行设置.我也会让ID成为一个private二传手:

public class Sample
{
    public Sample() {
        ID = GuidComb.Generate();
    }
    [Required]
    public Guid ID { get; private set; }
    [Required]
    public string FirstName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

顺序GUID

public static class GuidComb
    {
        public static Guid Generate()
        {
            var buffer = Guid.NewGuid().ToByteArray();

            var time = new DateTime(0x76c, 1, 1);
            var now = DateTime.Now;
            var span = new TimeSpan(now.Ticks - time.Ticks);
            var timeOfDay = now.TimeOfDay;

            var bytes = BitConverter.GetBytes(span.Days);
            var array = BitConverter.GetBytes(
                (long)(timeOfDay.TotalMilliseconds / 3.333333));

            Array.Reverse(bytes);
            Array.Reverse(array);
            Array.Copy(bytes, bytes.Length - 2, buffer, buffer.Length - 6, 2);
            Array.Copy(array, array.Length - 4, buffer, buffer.Length - 4, 4);

            return new Guid(buffer);
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 顺序GUID是一个愚蠢的想法.GUID的重点在于它是如此庞大的数字,当它被随机选择时,它保证它在全世界所有其他GUID中是唯一的. (5认同)
  • @binderbound 这不是一个愚蠢的想法。使用顺序 GUID 的原因是纯 GUID 是完全随机的。使用完全随机的任何内容(GUID、int 等)最终都会导致有效的不可排序,因此您的索引最终会变得非常碎片化且毫无意义,所有内容最终都需要进行全表扫描。使用顺序 GUID 意味着每一个都比上一个大,因此易于排序且不会产生碎片。这仅适用于数据库,在其他任何地方使用顺序 GUID 是没有意义的,但对于数据库来说,这是一个非常聪明的想法。 (2认同)

Tom*_*dia 8

这也可以通过属性来完成:

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid AddressID { get; set; }
Run Code Online (Sandbox Code Playgroud)


Chr*_*ler 6

如果我们忽略这是否是一个好主意周围的政治,那么@TombMedia的答案很可能就是您正在寻找的。

但是,如果您需要向现有表添加新列并希望指定 newId() 用于默认值,因为该字段不可为空,则在迁移类中使用它:

AddColumn(
    "dbo.Samples",
    "UUID", 
    c => c.Guid(nullable: false, defaultValueSql: "newId()")
);
Run Code Online (Sandbox Code Playgroud)

注意:这是一个老问题,在 EF6 中仍然相关,并且在寻求有关如何在 EF 迁移中使用 newId 的帮助时排名很高,这就是添加此答案的原因。


Joy*_*Joy 5

我在Nlog日志记录到数据库时遇到了同样的问题.我所做的是故意打开迁移文件并进行以下更改

CreateTable(
"dbo.Samples",
c => new
{
     ID = c.Guid(nullable: false,identity:true),
     FirstName = c.String(nullable: false)
})
.PrimaryKey(t => t.ID);
Run Code Online (Sandbox Code Playgroud)

identity参数实际上使用表中的defaultvalueas 创建newsequentialid() 了表.