2

我遵循了https://docs.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”时,如下所示。Cases 表中插入的数据和 CaseTypeId 字段的值为“null”

        modelBuilder.Entity<Case>().HasData(
            new Case {
                CaseId      = 1,
                //CaseTypeId  = 1,
                Name        = "Case 1",
                Description = "Case 1 Description",

            }
        );

问题在于案例实体中的外键属性“CaseTypeId”。

那么我在这里做错了什么?

4

1 回答 1

3

该错误当然不是用户友好的。但这是预览版(测试版)软件,因此预计不会完美运行。事实上,我无法用 3.0.0-preview6 重现它,但是当然更新数据库失败了,出现了无效的外键引用错误。

EF Core Model 种子数据有几个要求。首先,您必须明确指定 PK 和 FK 值。其次(这会导致您的问题),您必须同时播种主要数据和相关数据。

因此,用播种 FKCaseType所需的 PK 播种Cases 应该可以解决问题,例如

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",
    }
);
于 2019-07-13T08:41:46.630 回答