I'm seeding test data into two models, Author and Post. The seeding works for Author, but seems to fail silently for Post.
Edit: I think I've found the source of the issue. I've caught the exception, and the message is
Cannot insert explicit value for identity column in table
PostwhenIDENTITY_INSERTis set to OFF.
There may be a workaround for this in this StackOverflow post, but I was wondering if anyone has any ideas why this occurs? Is this because we shouldn't manually set the value of the primary key?
I am loosing following this Microsoft Docs tutorial, but using ASP.NET MVC Core 2.1. The basic strategy is that the Main() method in the Program class calls DbInitializer.Initialize(), which seeds the data if there are no Authors in the context.
I have stepped over the DbInitializer class, and the code goes through the same process for both models, looping through the seeded array, adding it to the context and (apparently) saving changes. However, while the Author database fields are populated with seed data, the Post fields are not.
Edit: While stepping through and inspecting the generated context, sometimes the Author fields have strange ID values and sometimes the Post fields have strange ID values :-2147492647, -2147492646, etc... I have tried to change PostID to ID on the off chance that that caused the issue, but the same issue occurs with that field name.
My second thought is wondering whether this has something to do with the many-to-one relationship between Post and Author. However, I've tried to seed Post data with only the Title field (so excluding the foreign key AuthorID), and that hasn't made a difference. I'm new to ASP.NET so my hope is that I'm missing something obvious. Thanks for any direction.
MyWebsiteContext.cs
using Microsoft.EntityFrameworkCore;
using MyWebsite.Models;
namespace MyWebsite.Models
{
public class MyWebsiteContext : DbContext
{
public MyWebsiteContext (DbContextOptions<MyWebsiteContext> options)
: base(options)
{
}
public DbSet<MyWebsite.Models.Author> Author { get; set; }
public DbSet<MyWebsite.Models.Post> Post { get; set; }
}
}
DbInitializer.cs
using MyWebsite.Models;
namespace MyWebsite.Data
{
public class DbInitializer
{
public static void Initialize(MyWebsiteContext context)
{
// Look for any authors; if none, seed DB.
if (context.Author.Any())
{
return; // DB has already been seeded.
}
var authors = new Author[]
{
new Author{ FirstName="Terry",LastName="Pratchett",SignUpDate=DateTime.Parse("2019-04-01")},
new Author{ FirstName="Neil",LastName="Gaiman",SignUpDate=DateTime.Parse("2019-03-02")},
};
foreach (Author a in authors)
{
context.Author.Add(a);
}
context.SaveChanges();
var posts = new Post[]
{
new Post{PostID=1,Title="Title of post 1"},
new Post{PostID=2,Title="Title of post 2"},
new Post{PostID=3,Title="Title of post 3"},
};
foreach (Post p in posts)
{
context.Post.Add(p);
}
context.SaveChanges();
}
}
}
Program.cs
using System;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MyWebsite.Data;
using MyWebsite.Models;
namespace MyWebsite
{
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<MyWebsiteContext>();
DbInitializer.Initialize(context);
}
catch(Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred creating the DB.");
}
}
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}
Post.cs
namespace MyWebsite.Models
{
public class Post // Post entity is dependent on Author class
{
public int PostID { get; set; } // primary key
public string Title { get; set; }
public int AuthorID { get; set; } // foreign key
public Author Author { get; set; }
}
}
Author.cs
namespace MyWebsite.Models
{
public class Author
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime SignUpDate { get; set; }
}
}