首页 > 解决方案 > 无法在 ef 核心中与 ApplicationUser 创建多对多关系

问题描述

我正在尝试在我的应用程序中创建 ApplicationUser 和 Courses 之间的多对多关系,但是在尝试将记录插入 CourseUsers 表时出现以下错误:

INSERT 语句与 FOREIGN KEY 约束“FK_CourseUsers_AspNetUsers_UserId”冲突。冲突发生在数据库“PIL”、表“dbo.AspNetUsers”、列“Id”中。该语句已终止。

我无法弄清楚问题是什么。我已经按照这里的文档:https ://docs.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key

我的用户模型:

    public class ApplicationUser : IdentityUser
{
    public DateTime Created { get; set; }
    public DateTime LastActive { get; set; }
    public List<CourseUser> CourseUsers { get; set; }
    public List<UserRole> UserRoles { get; set; }
}

我的课程模型:

    public class Course
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string Subtitle { get; set; }
    public string ThumbnailUrl { get; set; }
    public string PreviewVideoUrl { get; set; }
    public string Topics { get; set; }
    public decimal Cost { get; set; }
    public List<CourseContributor> CourseContributors { get; set; }
    public List<CourseUser> CourseUsers { get; set; }
    public List<Lesson> Lessons { get; set; }
    public string Grades { get; set; }
}

我的查找模型:

    public class CourseUser
{
    public int CourseId { get; set; }
    public Course Course { get; set; }
    public string UserId { get; set; }
    public ApplicationUser User { get; set; }
}

我的数据上下文:

public class DataContext : IdentityDbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base(options) { }

    public DbSet<Lesson> Lessons { get; set; }
    public DbSet<Course> Courses { get; set; }
    public DbSet<Contributor> Contributors { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<CourseContributor>()
        .HasKey(c => new { c.CourseId, c.ContributorId });

        modelBuilder.Entity<CourseContributor>()
            .HasOne(cc => cc.Contributor)
            .WithMany(c => c.CourseContributors)
            .HasForeignKey(ct => ct.ContributorId);

        modelBuilder.Entity<CourseContributor>()
            .HasOne(cc => cc.Course)
            .WithMany(c => c.CourseContributors)
            .HasForeignKey(ct => ct.CourseId);

        modelBuilder.Entity<CourseUser>()
            .HasKey(c => new { c.CourseId, c.UserId });

        modelBuilder.Entity<CourseUser>()
            .HasOne(u => u.User)
            .WithMany(c => c.CourseUsers)
            .HasForeignKey(us => us.UserId);

        modelBuilder.Entity<CourseUser>()
            .HasOne(cc => cc.Course)
            .WithMany(c => c.CourseUsers)
            .HasForeignKey(ct => ct.CourseId);

        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Lesson>().HasData(new Lesson() { Id = 1, Title = "Test Lesson", SubTitle = "Test Lesson Title", Description = "Test Lesson Description", DocUrl = "fdsafdsffds", ThumbnailUrl = "https://media.gettyimages.com/photos/stack-of-books-picture-id157482029?s=612x612", VideoUrl = "testVideoUrl", CourseId = 1 });
        modelBuilder.Entity<Contributor>().HasData(new Contributor() { Id = 1, FirstName = "Test First Name", LastName = "Test Last Name" });
        modelBuilder.Entity<Course>().HasData(new Course() { Id = 1, Title = "Test Course", Subtitle = "Test Course Title", Description = "Test Course Description", Cost = 20.00M, Grades = "1,2,3", PreviewVideoUrl = "Test Preview Video Url", ThumbnailUrl = "https://media.gettyimages.com/photos/stack-of-books-picture-id157482029?s=612x612", Topics = "Test Topic 1|Test Topic 2|Test Topic 3" });

        modelBuilder.Entity<CourseContributor>().HasData(new CourseContributor() { CourseId = 1, ContributorId = 1 });
        modelBuilder.Entity<CourseUser>().HasData(new CourseUser() { CourseId = 1, UserId = "1234" });
    }
}

编辑:这是用户播种方法

    public class Seed
{
    public static void SeedUsers(UserManager<ApplicationUser> userManager)
    {
        if (!userManager.Users.Any())
        {
            userManager.CreateAsync(new ApplicationUser { Id = "1234", UserName = "test@test.org", Created = DateTime.UtcNow, LastActive = DateTime.UtcNow, Email = "test@test.org" }, "Password1!").Wait();
        }
    }
}

和 Program.cs:

public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateWebHostBuilder(args).Build();
        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;
            try
            {
                var context = services.GetRequiredService<DataContext>();
                var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
                context.Database.Migrate();
                Seed.SeedUsers(userManager);
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occured during migration");
            }
        }

        host.Run();
    }

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

标签: .net-coreentity-framework-core

解决方案


您定义的模型在这里没有真正的问题。它只是您的测试数据,不完整。

将以下行添加到您的OnModelCreating()方法中:

modelBuilder.Entity<ApplicationUser>().HasData(new ApplicationUser {Id = "1234"});

推荐阅读