我将测试数据植入两个模型:Author
和Post
。播种对 Author
有效,但对于 Post
似乎默默失败。
编辑:我想我已经找到了问题的根源。我已经捕获了异常,消息是
Cannot insert explicit value for identity column in table
Post
whenIDENTITY_INSERT
is set to OFF.
this StackOverflow post 中可能有解决方法,但我想知道是否有人知道为什么会发生这种情况?这是因为我们不应该手动设置主键的值吗?
我正在失去关注this Microsoft Docs tutorial ,但使用 ASP.NET MVC Core 2.1。基本策略是,Program
类中的 Main()
方法调用 DbInitializer.Initialize()
,如果没有数据,则该方法会播种数据。上下文中的作者
。
我已经跳过了DbInitializer
类,并且代码对两个模型都经历了相同的过程,循环遍历种子数组,将其添加到上下文中并(显然)保存更改。但是,虽然 Author
数据库字段填充了种子数据,但 Post
字段却没有。
编辑:在单步执行和检查生成的上下文时,有时 Author
字段具有奇怪的 ID
值,有时 Post
字段具有奇怪的值ID
值:-2147492647、-2147492646 等...我尝试将 PostID
更改为 ID
,以防万一这会导致问题,但该字段名称也会出现同样的问题。
我的第二个想法是想知道这是否与帖子和作者之间的多对一关系有关。但是,我尝试仅使用 Title
字段(因此排除外键 AuthorID
)来种子 Post
数据,但这并没有有所作为。我是 ASP.NET 的新手,所以我希望我遗漏了一些明显的东西。感谢您的指导。
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; }
}
}
作者.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; }
}
}
最佳答案
尝试一下看看是否有效。自从我使用播种关系实体以来,我遇到了同样的问题。我的建议是尝试在代码中放入 try catch 来查看是否有任何异常
在您的 Program.cs 中
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
SeedData.Initialize(services).Wait();
}
然后像这样播种
public static async Task Initialize(IServiceProvider serviceProvider) {
using (var context = new ApplicationDbContext(
serviceProvider.GetRequiredService<DbContextOptions<ApplicationDbContext>>()))
{
if (!context.Posts.Any())
{
post.Comments = comments;
await SeedPost(context);
}
}
}
您可以看到我的 Post 实体有评论列表,因此我还将评论列表分配到 Post 对象中,然后播种一次
您可以查看我的完整代码 here
关于c# - 数据库播种仅适用于一个模型,不适用于第二个模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56913741/