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

Time:12-27

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 = "[email protected]",
    };
     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

CodePudding user response:

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.

  • Related