我遵循了 https://learn.microsoft.com/en-us/ef/core/modeling/data-seeding 上解释的数据播种过程。
使用"模型种子数据"方法为相关数据设定种子,如下所示:
public class CaseType
{
public int CaseTypeId { get; set; }
[Required]
public string Name { get; set; }
public ICollection<Case> Cases { get; set; }
}
public class Case
{
public int CaseId { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public CaseType CaseType { get; set; }
public int CaseTypeId { get; set; }
}
public class ApplicationDbContext : ApiAuthorizationDbContext<ApplicationUser>
{
public DbSet<CaseType> CaseTypes { get; set; }
public DbSet<Case> Cases { get; set; }
public ApplicationDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<CaseType>().HasData(
new CaseType {
CaseTypeId = 1,
Name = "Case Type 1",
}
);
modelBuilder.Entity<Case>().HasData(
new Case {
CaseId = 1,
CaseTypeId = 1,
Name = "Case 1",
Description = "Case 1 Description",
}
);
}
}
当我运行命令时出现以下错误:dotnet ef migrations add SeedDatabase
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 3.0.0-preview5.19227.1 initialized 'ApplicationDbContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: None
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.EntityFrameworkCore.Update.Internal.SharedTableEntryMap`1.GetMainEntry(IUpdateEntry entry)
at Microsoft.EntityFrameworkCore.Update.Internal.SharedTableEntryMap`1.GetOrAddValue(IUpdateEntry entry)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.DiffData(TableMapping source, TableMapping target, DiffContext diffContext)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Diff(TableMapping source, TableMapping target, DiffContext diffContext)+MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.DiffCollection[T](IEnumerable`1 sources, IEnumerable`1 targets, DiffContext diffContext, Func`4 diff, Func`3 add, Func`3 remove, Func`4[] predicates)+MoveNext()
at System.Linq.Enumerable.ConcatIterator`1.MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Sort(IEnumerable`1 operations, DiffContext diffContext)
at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace, String language)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Object reference not set to an instance of an object.
当我注释掉"CaseTypeId = 1"时,如下所示。插入的数据和案例表中的案例类型 ID 字段的值为"空">
modelBuilder.Entity<Case>().HasData(
new Case {
CaseId = 1,
//CaseTypeId = 1,
Name = "Case 1",
Description = "Case 1 Description",
}
);
问题出在案例实体中的外键属性"案例类型 ID"。
那么我在这里做错了什么?
该错误当然不是用户友好的。但这是预览版(测试版(软件,因此预计不会完美运行。事实上,我无法使用 3.0.0-preview6 重现它,但当然更新数据库失败了,出现无效的外键引用错误。
EF Core 模型种子数据有几个要求。首先,必须显式指定 PK 和 FK 值。其次(导致您的问题(,您必须为主要数据和相关数据设定种子。
因此,用播种Case
FK所需的PK播种CaseType
应该可以解决问题,例如
modelBuilder.Entity<CaseType>().HasData(
new CaseType
{
CaseTypeId = 1, // <--
Name = "Case Type 1",
}
);
modelBuilder.Entity<Case>().HasData(
new Case
{
CaseId = 1,
CaseTypeId = 1, // <--
Name = "Case 1",
Description = "Case 1 Description",
},
new Case
{
CaseId = 2,
CaseTypeId = 1, // <--
Name = "Case 2",
Description = "Case 2 Description",
}
);