实体框架核心自动生成的GUID

时间:2018-11-27 05:00:45

标签: c# entity-framework-core asp.net-core-2.1

有人可以指导我想要 result = [] ids = np.unique(a) for id in ids: line = [id] for band in range(0, b.shape[0]): cell = b[band][np.where(a == id)] line.append(cell.mean()) # line.append(cell.min()) # line.append(cell.max()) # line.append(cell.std()) line.append(cell.sum()) line.append(np.median(cell)) result.append(line) 作为表的 primeryKey ,在插入时具有数据库生成的值。

guid

但是它给出了[Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid Id { get; set; }

  

无法添加实体类型“用户”的种子实体,因为没有为必需的属性“ Id”提供值。

这是我的实际模型类和DbContxt类:

error

然后在DbContxt中输入

public class BaseModel
{
     [Key]
     [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
     public Guid Id { get; set; }

     [Required]
     [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
     public DateTime CreatedOn { get; set; } = DateTime.UtcNow;


     [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
     public DateTime? UpdatedOn { get; set; }

     [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
     public DateTime LastAccessed { get; set; }
 }

 public class User : BaseModel
 {
        [Required]
        [MinLength(3)]
        public string Name { get; set; }

        [Required]
        [MinLength(3)]
        [EmailAddress]
        public string Email { get; set; }

        [Required]
        [MinLength(6)]
        public string Password { get; set; }
  }

请帮助!

8 个答案:

答案 0 :(得分:3)

您遇到的问题并非专门针对自动生成的Guid。 任何自动生成的键值(包括常用的自动增量(标识)列)也会发生同样的情况。

这是由特定的Data SeedingHasData)要求引起的:

  

此类种子数据由迁移管理,并且需要在不连接数据库的情况下生成用于更新数据库中已有数据的脚本。这施加了一些限制:

     
      
  • 即使通常由数据库生成,也需要指定主键值。它将用于检测迁移之间的数据更改。
  •   
  • 如果以任何方式更改主键,则先前的种子数据将被删除。
  •   

注意第一个项目符号。因此,对于正常的CRUD,虽然您的PK将自动生成,但要求在使用HasData流利的API时指定它,并且该值必须是恒定的(不变),因此您可以不要使用Guid.NewGuid()。因此,您需要生成多个Guid,使用它们的字符串表示形式并使用类似以下内容的东西:

mb.Entity<User>().HasData(
    new User() { Id = new Guid("pre generated value 1"), ... },
    new User() { Id = new Guid("pre generated value 2"), ... },
    new User() { Id = new Guid("pre generated value 3"), ... }
    );

答案 1 :(得分:2)

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]在GUID字段上可在Entity Framework 6.x上使用,可能还不在EF Core中!

解决方案是:

1)首先,按如下所示编写您的BaseModel类:

public class BaseModel
{
    [Key]
    public Guid Id { get; set; }

    public DateTime CreatedOn { get; set; } = DateTime.UtcNow;

    public DateTime? UpdatedOn { get; set; }

    public DateTime LastAccessed { get; set; }
}

2)然后,您的OnModelCreating()中的DbContext方法应如下:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
      base.OnModelCreating(modelBuilder);

      modelBuilder.Entity<YourEntity>().Property(x => x.Id).HasDefaultValueSql("NEWID()");

      modelBuilder.Entity<User>().HasData(
            new User() { Id  = Guid.NewGuid(), Email = "Mubeen@gmail.com", Name = "Mubeen", Password = "123123" },
            new User() { Id = Guid.NewGuid(), Email = "Tahir@gmail.com", Name = "Tahir", Password = "321321" },
            new User() { Id = Guid.NewGuid(),  Email = "Cheema@gmail.com", Name = "Cheema", Password = "123321" }
            );
 }

现在创建一个全新的迁移并相应地更新数据库。希望您的问题得到解决!

答案 2 :(得分:2)

您可以在代码优先迁移文件中使用defaultValueSql: "newid()"

例如;

 public override void Up()
    {
        CreateTable(
            "dbo.ExampleTable",
            c => new
            {
                Id = c.Guid(nullable: false, identity: true, defaultValueSql: "newid()"),               
                RowGuid = c.Guid(nullable: false, defaultValueSql: "newid()"),

            })
            .PrimaryKey(t => t.Id);           
    }

答案 3 :(得分:1)

GUIDIdentity framework处理,而不是由EF处理,因此,要使用GUID,需要执行以下操作

[Key]
public Guid Id { get; set; }

然后在插入表之前准备模型

new User() { Id = Guid.NewGuid(), Email = "Mubeen@gmail.com", Name = "Mubeen", Password = "123123" },

答案 4 :(得分:1)

除了手动更新迁移外,您还可以在OnModelCreating中实现一个更新,例如将更新添加到迁移中

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // guid identities
    foreach (var entity in modelBuilder.Model.GetEntityTypes()
        .Where(t =>
            t.ClrType.GetProperties()
                .Any(p => p.CustomAttributes.Any(a => a.AttributeType == typeof(DatabaseGeneratedAttribute)))))
    {
        foreach (var property in entity.ClrType.GetProperties()
            .Where(p => p.PropertyType == typeof(Guid) && p.CustomAttributes.Any(a => a.AttributeType == typeof(DatabaseGeneratedAttribute))))
        {
            modelBuilder
                .Entity(entity.ClrType)
                .Property(property.Name)
                .HasDefaultValueSql("newsequentialid()");
        }
    }

}  

答案 5 :(得分:0)

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
        {
            b.Property<string>("Id").HasMaxLength(36)
                .ValueGeneratedOnAdd();
});

答案 6 :(得分:0)

  1. 创建易于使用的扩展方法:
namespace Microsoft.EntityFrameworkCore
{
    using System;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Linq;
    using System.Reflection;
    public static class ModelBuilderExtensions
    {
        public static void SetDefaultValuesTableName(this ModelBuilder modelBuilder)
        {
            foreach (var entity in modelBuilder.Model.GetEntityTypes().Where(x => x.ClrType.GetCustomAttribute(typeof(TableAttribute)) != null))
            {
                var entityClass = entity.ClrType;

                foreach (var property in entityClass.GetProperties().Where(p => (p.PropertyType == typeof(DateTime) || p.PropertyType == typeof(Guid)) && p.CustomAttributes.Any(a => a.AttributeType == typeof(DatabaseGeneratedAttribute))))
                {
                    var defaultValueSql = "GetDate()";
                    if (property.PropertyType == typeof(Guid))
                    {
                        defaultValueSql = "newsequentialid()";
                    }
                    modelBuilder.Entity(entityClass).Property(property.Name).HasDefaultValueSql(defaultValueSql);
                }
            }
        }
    }
}
  1. 修改您的OnModelCreating方法
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.SetDefaultValuesTableName();
    }
  1. 利润

Source

答案 7 :(得分:0)

如果您只需要在创建和保存新实体时获得一个自动值,您也可以在构造函数中进行:

public class BaseModel
{
   public BaseModel()
   {
      Id = new Guid();
   }

   [Key]
   public Guid Id { get; set; }

   public DateTime CreatedOn { get; set; } = DateTime.UtcNow;

   public DateTime? UpdatedOn { get; set; }

   public DateTime LastAccessed { get; set; }
}