简体   繁体   中英

Seeding data. SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint

I'm working in asp.net.core Entityframework 6, CodeFirst Approach. I believe i'm seeding the data in a wrong order, or in the wrong way. I use a similar approach for artist/author/voice/associatedNames. i get similar error as all of them.

The entire error reads for artist or author SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_AssociatedNames_artistModels_ArtistModelArtistId". The conflict occurred in database "BookDB", table "dbo.artistModels", column 'ArtistId'. What is the correct way of saving the moduls? I read this articale EF Code First The INSERT statement conflicted with the FOREIGN KEY constraint This is where i believe i'm approaching the saving wrong.

Edit: i managed to recreated the problem, in another project and got the same error.

public class BookModel
{
   [Key]
   public int BookId { get; set; }
   public ICollection<AssociatedNames>? AssociatedNames { get; set; }
   public ICollection<AuthorModel>? Authormodels { get; set; }
}

public class AssociatedNames
{
   [Key]
   public int AssociatedNamesId { get; set; }
   public string? nameString { get; set; }
   public int? BookId{ get; set; }
   public BookModel? bookModel { get; set; }
   public int? AuthorId { get; set; }
   public AuthorModel AuthorModel { get; set; }
}

public class AuthorModel
{
  [Key]
  public int AuthorID { get; set; }
  public string Firstname { get; set; }     
  public ICollection<AssociatedNames>? AssociatedNames { get; set; }  
  public int? BookId { get; set; }
  public BookModel? bookModel{ get; set; }
}

public class SeedData
{
  private readonly UserManager<IdentityUser> userManager;
  private readonly SignInManager<IdentityUser> signInManager;
  private readonly BookDBContext bookDBContext;
  public AuthorModel AuthorModels { get; set; }
  public BookModel BookModels { get; set; }
  public AssociatedNames _AssociatedNames { get; set; }

  public SeedData(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager, BookDBContext bookDBContext)
   {
    this.userManager = userManager;
    this.signInManager = signInManager;
    this.bookDBContext = bookDBContext;
    }
  public async Task seedData()
    {                      
    var user = new IdentityUser
    {
     UserName = "TestUSer",
     Email = "TestUser@hotmail.com",
    };
     var newAuthor = new AuthorModel { FirstName = "Charles" };
     bookDBContext.AuthorModels.Add(newAuthor);
     var newAss = new AssociatedNames { nameString = "Kallax" };
     bookDBContext.AssociatedNames.Add(newAss);
     var Newbook = new BookModel { BookName = "HelloWorld", AssociatedNames = new List<AssociatedNames> { newAss } };
     bookDBContext.SaveChanges();
     var result = await userManager.CreateAsync(user, "Test!112");
            
     }
  }

On the Program.cs

   builder.Services.AddScoped<SeedData>();
static void SeedDatainitialize(IHost host)
{
    var scopefactorty = host.Services.GetService<IServiceScopeFactory>();
    using (var scope = scopefactorty.CreateScope())
    {
    var seed = scope.ServiceProvider.GetService<SeedData>();
      seed.seedData().Wait();
    }
 }
     

The Context.

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

    }
    public DbSet<AuthorModel> AuthorModels { get; set; }
    public DbSet<AssociatedNames> AssociatedNames { get; set; }
    public DbSet<BookModel> BookModels { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

        base.OnModelCreating(modelBuilder);


    }
 }
 

I tried using different void methods to save them at different time, so they are fully created at different stages. Then add the object to the collections. and repeat. Did not work

So i solved it, i am unsure why this worked. Either EF had problems with keying the right FK.

public class AssociatedNames
{
    [Key]
    public int AssociatedNamesId { get; set; }
    public string? nameString { get; set; }
    public int? BookModelId{ get; set; }
    public BookModel? BookModels{ get; set; }

    [ForeignKey("AuthorModel")]
    public int? AuthorID { get; set; }
    public AuthorModel AuthorModel { get; set; }

    [ForeignKey("ArtistModel")]
    public int? ArtistId { get; set; }
    public ArtistModel ArtistModel { get; set; }

    [ForeignKey("VoiceActorModel")]
    public int? VoiceActorId { get; set; }
    public VoiceActorModel VoiceActorModel { get; set; }
}

In my Model Creation i added these lines.

   modelBuilder.Entity<BookModel>().Navigation(e => e.Authormodels).AutoInclude();
        modelBuilder.Entity<BookModel>().Navigation(e => e.ArtistModels).AutoInclude();
        modelBuilder.Entity<BookModel>().Navigation(e => e.VoiceActors).AutoInclude();

I noticed when i wrote the code that i didn't include the other classes when calling, then adding the AssociatedNames.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM