MVC5 EF6种子方法:无法将NULL插入列"Id"表中的AspNetUsers [英] MVC5 EF6 Seed Method: Cannot insert NULL into column 'Id' table AspNetUsers

查看:141
本文介绍了MVC5 EF6种子方法:无法将NULL插入列"Id"表中的AspNetUsers的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

实体框架6,MVC5,ASP Identity 2.0.

Entity Framework 6, MVC5, ASP Identity 2.0.

我已经按照这2个教程创建了Web应用程序的登录部分:第1部分-第2部分

I have followed this 2 tutorials to create the login part of the web application: part 1 - part 2

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

I created my own AppUser class from IdentityUser Class in another library project. I also have my data context from the IdentityDbContext

    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; }
}

运行种子方法时,出现以下错误

When I run the seed method I get the following error

System.Data.SqlClient.SqlException:无法将值NULL插入表'CRM1.dbo.AspNetUsers'的列'Id'中;列不允许为空. INSERT失败. 该声明已终止.

System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'Id', table 'CRM1.dbo.AspNetUsers'; column does not allow nulls. INSERT fails. The statement has been terminated.

以下是播种方法:

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会自动执行此操作,但不会.

So Id gets a value but EF says it is inserting NULL. I tried by not giving any value to Id thinking EF would do it automatically but no.

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

What is the approach to seed an AspNetUser with my context? I saw different tutorials but it does not apply to my extended AppUser class and DataContext.

谢谢

推荐答案

从您的代码中删除以下行:

Remove this line from your code:

modelBuilder.Entity<AppUser>().Property(u => u.Id).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);

,还有您的User中的这部分:

and also this part from your User:

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

您无需覆盖此属性,只需使用父级的属性(实体框架将其映射).

You don't need to override this property, just use the parent's property (entity framework will map it).

说明::像您一样配置Id属性时,您是在告诉实体框架该属性值来自数据库,因此插入时它完全忽略了传递给该属性的值进入数据库.

Explanation: when you configure the Id property like your did, you're telling entity framework the property value comes from database, so it totally ignores the value you passed to this property when inserting into database.

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

On the other hand, if your column inside your database table does not have a default value, it will fails, because entity framework is not providing a value for it.

因此,您需要决定:表必须具有默认值,或者应删除该字段的HasDatabaseGeneratedOption选项.

So you need to decide: either your table must have a default value, or you should remove that HasDatabaseGeneratedOption option for that field.

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

The thing is that IdentityUser uses a string as key, which normally would be a Guid. Since EF won't generate Id for you automatically, and your column won't as well, you can create a constructor to your User do like this:

public AppUser()
{
    Id = Guid.NewGuid().ToString();
}

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

Whenever you create a new user, it will have a new Guid as Id....when you read an existing user from your context, although your constructor will generate it when being instantiated by EF, EF will then load Id value from your table over it (ignoring the one provided in constructor).

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

This means the autogenerated Guid inside your constructor will be used only for new instances.

这篇关于MVC5 EF6种子方法:无法将NULL插入列"Id"表中的AspNetUsers的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆