首页 > 解决方案 > 一对多关系,数据未在数据库中播种

问题描述

我从它正常工作的地方得到了这段代码。Department 类和 ApplicationUser 类具有一对多的关系。我正在尝试播种数据。角色被添加到数据库中,但不是用户或部门。这是 ApplicationUser 类

  public class ApplicationUser : IdentityUser<int>
    {

        //n-1 relationship
        public int DepartmentId { get; set; }
        public Department Department { get; set; }

        [DisplayName("First Name")]
        [Required, MaxLength(50, ErrorMessage = "Name cannot exceed 50 characters")]
        public string FirstName { get; set; }

        [DisplayName("Middle Name")]
        public string MiddleName { get; set; }

        [DisplayName("Last Name")]
        [Required]
        public string LastName { get; set; }
        }

这是部门班

public class Department : Entity
    {
        public string Name { get; set; }
        public ICollection<ApplicationUser> Employees { get; set; }

    }

这是上下文类

 public class ManageContext : IdentityDbContext<ApplicationUser,IdentityRole<int>,int>
    {
        public ManageContext(DbContextOptions<ManageContext> dbContextOptions) :base(dbContextOptions)
        {

        }

        public DbSet<Department> Departments { get; set; }

        //the name of the table will be same as the name of the class
        private static void SetTableNamesAsSingle(ModelBuilder builder)
        {
            // Use the entity name instead of the Context.DbSet<T> name
            foreach (var entityType in builder.Model.GetEntityTypes())
            {
                builder.Entity(entityType.ClrType).ToTable(entityType.ClrType.Name);
            }
        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            SetTableNamesAsSingle(builder);

            base.OnModelCreating(builder); 

        }
    }

有 2 个单独的类来播种数据。它们中有静态方法来播种和创建角色和用户。这是用于为部门类播种的 dataseeder 类

public class DataSeeder
    {
        public static async Task SeedAsync(ManageContext manageContext, ILoggerFactory loggerFactory, int? retry = 0)
        {
            int retryForAvailability = retry.Value;

            try
            {
                await SeedDepartmentAsync(manageContext);
                
            }
            catch (Exception exception)
            {
                if (retryForAvailability < 10)
                {
                    retryForAvailability++;
                    var log = loggerFactory.CreateLogger<ManageContext>();
                    log.LogError(exception.Message);
                    await SeedAsync
                        (manageContext, loggerFactory, retryForAvailability);
                }
                throw;
            }
        }


        private static async Task SeedDepartmentAsync(ManageContext manageContext)
        {

            if (manageContext.Departments.Any())
                return;

            var department = new List<Department>()
            {
                new Department() { Name ="HR"},
                new Department() { Name = "IT"}
            };


            manageContext.Departments.AddRange(department);
            await manageContext.SaveChangesAsync();
        }
 }

这是创建角色和用户并填充数据库的 identityseeder 类

  public class IdentitySeeder
    {
      
        #region Public Methods
        public static void Seed(
           ManageContext manageContext,
            RoleManager<IdentityRole<int>> roleManager,
            UserManager<ApplicationUser> userManager
            )
        {
            // Create default Users (if there are none)
            if (!manageContext.Users.Any())
            {
                CreateUsers(manageContext, roleManager, userManager)
                    .GetAwaiter()
                    .GetResult();
            }

        }
        #endregion

        #region Seed Methods
        private static async Task CreateUsers(
            ManageContext manageContext,
            RoleManager<IdentityRole<int>> roleManager,
            UserManager<ApplicationUser> userManager)
        {
            // local variables
            DateTime createdDate = new DateTime(2021, 03, 17, 12, 30, 00);
            DateTime lastModifiedDate = DateTime.Now;

            string role_Administrator = "Administrator";
            string role_RegisteredUser = "RegisteredUser";

            //Create Roles (if they doesn't exist yet)
            if (!await roleManager.RoleExistsAsync(role_Administrator))
            {
                await roleManager.CreateAsync(new IdentityRole<int>(role_Administrator));
            }
            if (!await roleManager.RoleExistsAsync(role_RegisteredUser))
            {
                await roleManager.CreateAsync(new IdentityRole<int>(role_RegisteredUser));
            }

            // Create the "Admin" ApplicationUser account
         
            var user_Admin = new ApplicationUser()
            {
                SecurityStamp = Guid.NewGuid().ToString(),
                FirstName = "Breta",
                LastName = "Collins",
                Role = "Administrator",
                Email = "bretacollins@mail.com",
                UserName = "breta.collins",
              

            };
            // Insert "Admin" into the Database and assign the "Administrator" and "Registered" roles to him.
          
            if (await userManager.FindByIdAsync(user_Admin.Id.ToString()) == null)
            {
                await userManager.CreateAsync(user_Admin, "Password1!");
               
                await userManager.AddToRoleAsync(user_Admin, role_Administrator);

               
                // Remove Lockout and E-Mail confirmation.
                user_Admin.EmailConfirmed = true;
                user_Admin.LockoutEnabled = false;



            }

            await manageContext.SaveChangesAsync();
        }

        #endregion
    }
}

这是程序类

 public class Program
    {

        public static void Main(string[] args)
        {
            var host = CreateWebHostBuilder(args).Build();

            SeedDatabase(host);

            host.Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>();

        private static void SeedDatabase(IWebHost host)
        {
            using (var scope = host.Services.CreateScope())
            {
                var services = scope.ServiceProvider;
                var loggerFactory = services.GetRequiredService<ILoggerFactory>();

                try
                {
                    var manageContext = services.GetRequiredService<ManageContext>();
                    var roleManager = services.GetRequiredService<RoleManager<IdentityRole<int>>>();
                    var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
                    IdentitySeeder.Seed(manageContext ,roleManager ,userManager);

                   
                }
                catch (Exception exception)
                {
                    var logger = loggerFactory.CreateLogger<Program>();
                    logger.LogError(exception, "An error occurred seeding the DB.");
                    Console.WriteLine(exception);
                }
            }
        }

    }

我是新手,并将其作为我的学习项目。我得到的错误是“INSERT 语句与 FOREIGN KEY 约束“FK_AspNetUsers_Department_DepartmentId”冲突。冲突发生在数据库“ManageDatabase”、表“dbo.Department”、列“ID”中。语句已终止。” 我不知道如何解决这个错误。谢谢您的帮助。

标签: c#.net-coreasp.net-core-mvc

解决方案


您必须在播种 ApplicationUser 之前播种 Department 表。由于 DepartmentId 不可为空,因此您必须将 DepartmentId 分配给新的 ApplicationUser 实例:

var user_Admin = new ApplicationUser()
            {
                SecurityStamp = Guid.NewGuid().ToString(),
                FirstName = "Breta",
                LastName = "Collins",
                Role = "Administrator",
                Email = "bretacollins@mail.com",
                UserName = "breta.collins",
                DepartmentId=1 //or what you need

            };

或者您可以更改 DepartmentId 类型

  public int? DepartmentId { get; set; }

但在这种情况下,您的 Db 表的 DepartmentId 列也应该为空。


推荐阅读