EF Core 2中Azure数据库的Seeder方法

时间:2019-05-14 19:23:23

标签: azure asp.net-core entity-framework-core azure-sql-database

将数据植入Azure数据库的正确方法是什么?当前正在开发中,我有一个Seeder方法可以插入前几个用户和产品。用户(包括管理员用户)的用户名和密码被硬编码到Seed方法中,这是可以接受的做法吗?

就产品而言,我有一个带有产品名称和说明的json文件-在开发过程中,seeder方法将迭代并插入数据。

1 个答案:

答案 0 :(得分:0)

回答您的问题“将用户(包括管理员用户)用户名和密码硬编码到Seed方法中,这是可以接受的做法吗?”

否,尽管您可以将其保留为加密模式并进行种子植入,但仍应以明文格式保留密码。

在EF Core 2.1中,播种工作流程完全不同。现在有了Fluent API逻辑来定义OnModelCreating中的种子数据。然后,当您创建迁移时,将种子转换为迁移命令以执行插入操作,并最终转换为该特定迁移执行的SQL。根据您在OnModelCreating方法中所做的更改,进一步的迁移将知道插入更多数据,甚至执行更新和删除。

假设模型中的三个类是Magazine,Article和Author。一本杂志可以有一个或多个文章,而一篇文章可以有一个作者。还有一个PublicationsContext,使用SQLite作为数据提供程序,并设置了一些基本的SQL日志记录。

让我们举一个单一实体类型的例子。

让我们从最简单的方式开始,看看为杂志提供种子数据的样子。

新的播种功能的关键是HasData Fluent API方法,您可以在OnModelCreating方法中将其应用于实体。

这是杂志类型的结构:

public class Magazine
{
  public int MagazineId { get; set; }
  public string Name { get; set; }
  public string Publisher { get; set; }
  public List<Article> Articles { get; set; }
}

它具有键属性MagazineId,两个字符串和文章类型列表。现在,为一本杂志的数据添加种子:

protected override void OnModelCreating (ModelBuilder modelBuilder)
{
  modelBuilder.Entity<Magazine> ().HasData
    (new Magazine { MagazineId = 1, Name = "MSDN Magazine" });
}

这里有两点要注意:首先,我明确设置了关键属性MagazineId。其次,我没有提供发布者字符串。

接下来,我将添加此模型的第一个迁移。我恰好在该项目中使用Visual Studio Code,这是一个.NET Core应用程序,因此我使用的是CLI迁移命令,即“ dotnet ef迁移添加初始化”。生成的迁移文件包含所有通常的CreateTable和其他相关逻辑,然后是插入新数据的代码,并指定表名称,列和值:

migrationBuilder.InsertData(
  table: "Magazines",
  columns: new[] { "MagazineId", "Name", "Publisher" },
  values: new object[] { 1, "MSDN Magazine", null });

插入主键值对我很重要-特别是在我检查了如何在迁移文件中进一步定义MagazineId列之后。该列应自动递增,因此您可能不希望该值被明确插入:

MagazineId = table.Column<int>(nullable: false)
                        .Annotation("Sqlite:Autoincrement", true)

让我们继续看看这是如何实现的。使用迁移脚本命令“ dotnet ef迁移脚本”来显示将发送到数据库的内容,我可以看到主键值仍将插入到键列中:

INSERT INTO "Magazines" ("MagazineId", "Name", "Publisher")
VALUES (1, 'MSDN Magazine', NULL);

那是因为我的目标是SQLite。如果提供,SQLite将插入一个键值,以覆盖自动增量。但是,对于SQL Server数据库,那肯定不会即时做到这一点呢?

我切换了上下文,以使用SQL Server提供程序进行调查,并看到由SQL Server提供程序生成的SQL包含用于临时将IDENTITY_INSERT设置为ON的逻辑。这样,提供的值将被插入到主键列中。谜团解决了!

您可以使用HasData一次插入多行,但请记住,HasData特定于单个实体。您无法使用HasData将插入内容合并到多个表中。在这里,我要一次插入两本杂志:

modelBuilder.Entity<Magazine>()
           .HasData(new Magazine{MagazineId=2, Name="New Yorker"},
                    new Magazine{MagazineId=3, Name="Scientific American"}
           );

有关完整示例,您可以浏览此示例repo

希望有帮助。