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
Post
whenIDENTITY_INSERT
is 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; }
}
}