首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MVC5 EF6种子方法:无法将NULL插入列'Id‘表AspNetUsers

MVC5 EF6种子方法:无法将NULL插入列'Id‘表AspNetUsers
EN

Stack Overflow用户
提问于 2017-01-25 15:59:03
回答 2查看 6.7K关注 0票数 4

实体框架6,MVC5,ASP 2.0。

我遵循这两个教程来创建web应用程序的登录部分:第1部分 - 第2部分

我从另一个库项目中的AppUser类中创建了自己的IdentityUser类。我还拥有来自IdentityDbContext的数据上下文

代码语言:javascript
复制
    public class DataContext: IdentityDbContext<AppUser>
    {
       public DataContext(): base("DefaultConnection") { }

       protected override void OnModelCreating(DbModelBuilder modelBuilder)
       {
           modelBuilder.Entity<AppUser>().Property(u => u.Id).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);
           base.OnModelCreating(modelBuilder);
      }
    }

public class AppUser : IdentityUser
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public override string Id { get; set; }

    [Required]
    [Display(Name ="First Name")]
    [MaxLength(100)]
    public string FirstName { get; set; }

    [Required]
    [Display(Name = "Last Name")]
    [MaxLength(100)]
    public string LastName { get; set; }

    [MaxLength(100)]
    public string Title { get; set; }

    [Required(ErrorMessage = "Email is required.")]
    [Display(Description = "Email")]
    public override string Email { get; set; }

    [MaxLength(20)]
    public string Phone { get; set; }

    [Range(0,9999)]
    [Display(Name = "Extension")]
    public int PhoneExtension { get; set; }

    [Display(Name = "Active")]
    [DefaultValue(true)]
    public bool IsActive { get; set; }
}

运行种子方法时,会得到以下错误

System.Data.SqlClient.SqlException:无法将值NULL插入“Id”列、表“CRM1.dbo.AspNetUser”;列不允许空值。插入失败。声明已被终止。

以下是播种方法:

代码语言:javascript
复制
protected override void Seed(CRM.DAL.Data.DataContext context)
    {
        context.AccessLevels.AddOrUpdate(al => al.Label,
            new Model.AccessLevel { AccessLevelID = 1, Label = "Admin", Description = "Full access to the CRM data" },
            new Model.AccessLevel { AccessLevelID = 2, Label = "Customer Service", Description = "Full access to the CRM data" },
            new Model.AccessLevel { AccessLevelID = 3, Label = "Sales", Description = "Full access to the CRM data" }
            );

        if (!(context.Users.Any(u => u.UserName == "admin@admin.com")))
        {
            var userStore = new UserStore<AppUser>(context);
            var userManager = new UserManager<AppUser>(userStore);
            var userToInsert = new AppUser
            {
                Id = "1",
                FirstName = "Admin",
                LastName = "Admin",
                Title = "Administrator",
                Email = "admin@admin.com",
                PhoneExtension = 0,
                IsActive = true,
                AccessLevelID = 1,
                EmailConfirmed = true,
                PhoneNumberConfirmed = true,
                TwoFactorEnabled = false,
                LockoutEnabled = false,
                AccessFailedCount = 0,
                UserName = "admin"
            };
            userManager.Create(userToInsert, "password");
        }

    }

因此Id得到一个值,但EF表示它正在插入NULL。我试着不给Id任何价值,以为EF会自动完成,但没有。

用我的上下文播撒AspNetUser的方法是什么?我看到了不同的教程,但它不适用于我的扩展AppUser类和DataContext。

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-25 16:21:15

从代码中删除这一行:

代码语言:javascript
复制
modelBuilder.Entity<AppUser>().Property(u => u.Id).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);

这部分也来自于你的User

代码语言:javascript
复制
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public override string Id { get; set; }

您不需要覆盖该属性,只需使用父属性(实体框架将映射它)。

解释:当您像did一样配置Id属性时,您将告诉实体框架属性值来自数据库,因此它完全忽略了插入到数据库时传递给该属性的值。

另一方面,如果数据库表中的列没有默认值,它将失败,因为实体框架没有为其提供值。

因此,您需要决定:要么您的表必须有一个默认值,要么您应该删除该字段的HasDatabaseGeneratedOption选项。

问题是,IdentityUser使用string作为键,通常是Guid。由于EF不会自动为您生成Id,而且您的列也不会自动生成constructor,所以您可以为您的User创建一个constructor,如下所示:

代码语言:javascript
复制
public AppUser()
{
    Id = Guid.NewGuid().ToString();
}

每当您创建一个新用户时,它都将有一个新的Guid作为Id....when从您的上下文中读取一个现有用户,尽管您的构造函数在被EF实例化时会生成它,然后EF将从您的表上加载Id值(忽略构造函数中提供的那个)。

这意味着构造函数中的自动生成的Guid将仅用于新实例。

票数 2
EN

Stack Overflow用户

发布于 2017-06-27 21:21:51

接下来的事发生在我身上。我按照本指南将ASP.NET标识中的用户的主键从Guid更改为Int。

https://learn.microsoft.com/en-us/aspnet/identity/overview/extensibility/change-primary-key-for-users-in-aspnet-identity

我已经进行了一些迁移,因此EF试图将Id从nvarchar(128)更改为int。这起作用了,但Identity Specification从未从“不”转到“是”。通过删除所有以前的迁移,删除数据库,然后对所有更改进行新的迁移来解决这个问题。由于我们还处于早期发展阶段,这并不是一个问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41856085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档