• Entity Framework Core 2.1,添加种子数据


    EFCore 2.1出来有一段时间了,里面的新功能还没怎么用,今天研究下如何使用EF Core 2.1添加种子数据。

    这部分的官方文档地址是:https://docs.microsoft.com/en-us/ef/core/modeling/data-seeding

    我们在开发时总是需要添加一些种子数据的,所以这个功能还是比较有用的。

    准备工作

    我建立了一个ASP.NET Core项目,里面有几个Model,其中一个是省份Province,另一个是城市City:

    里面还涉及到其它的Model,不过本文用不到,就不贴了。

    该项目使用的数据库是MSSQL LocalDB。并已经做好了上述Models的迁移工作。

    该数据库里面存在过一些数据,但是现在都被我删除了。

    添加第一个种子数据

    直接在DBContext的OnModelCreating方法里使用HasData()方法:

    这里我添加了一个省份的种子数据,并写上了主键Id的值

    数据库该表的主键Id是int自增的。Id为1的数据曾经存在过,但是被我删除了。

    然后看看会发生什么

    生成的迁移类

    命令:Add-Migration Xxx

    看一下生成的迁移类的内容:

    生成的SQL脚本

    命令:Script-Migration

    这是里面关于插入数据的部分:

     迁移到数据库

    命令:Update-Database -Verbose

    结果是成功的。

    看红线那两句话,EFCore在执行的过程中临时更改了设置,可以插入主键的值,然后又禁用了插入主键。

    数据库里面的数据

    虽然曾经存在过Id为1的数据(然后被删除了),但是Id为1的种子数据仍然可以插入进去。

    种子数据的主键必须有值

    我再添加一个没有主键Id值的种子数据:

    然后Add-Migration,看看会发生什么:

    报错了,所以主键值是必填的。

    当我填写了主键值之后,一切都是好用的了:

    更改现有的种子数据

    我在HasData方法里更改了现有的种子数据,但是主键的值并没有改:

    执行Update-Database时的SQL语句:

    可以看到是根据主键对数据库里面的数据进行Update动作。

    其结果也和我想的一样,就是更新了现有的数据:

    如果我把HasData里种子数据的主键值修改了

    我把四川的主键从2改为3。

    看下生成的迁移文件:

    先删除了之前添加的Id为2的种子数据,然后把插入了一笔Id为3的数据。

    看下SQL:

    也是先Delete,再Insert。

    数据库里:

    种子数据为什么要指定主键的值?

     因为在团队开发时,这样可以确保不同的开发人员、电脑、服务器上,在同一个迁移版本具有相同的种子数据

    添加关联种子数据

    Province和City是一对多的关系,也就是说一个Province可以有多个City,而且它们之间有导航属性。

    下面看看一次性添加Province和City是否可以行,我直接在HasData方法里这样写:

    然后Add-Migration

    这样做不行。我必须单独添加City的种子数据,并且设置好外键

    所以正确的做法是:

    这次Add-Migration没有报错,迁移也成功了,看一下最后的数据:

    OK

    如果无法在Model里设置主键/外键

    有时,我们在主从关系的Model里不明确定义外键;有时候我们Model的主键是private set的;

    这时我们就无法在HasData里设置主键/外键的值了,那么如何来添加种子数据呢?

    答案就是使用匿名类

    我把City Model里的外键去掉(导航属性仍然保留,和Province的主从关系依然存在):

    然后就可以这样添加种子数据:

    迁移后的数据:

    结果仍然如预期一样。

    如果主键是Guid类型呢?

    看下数据:

    貌似没问题。

    如果我不修改这个种子数据,再执行一次迁移呢?

    看一下这时的迁移文件:

    删除原来的数据,再插入一个新的数据。。

    数据库里也是这样的:

    所以最好的办法是把Guid的值放在一个变量里

    然后再操作一遍:

    这样就不会出现“把原有数据删掉,再重新插入”这种操作了。

    其它

    使用context.Database.EnsureCreated()会创建一个新的数据库,并包含有种子数据。但是如果数据库已经存在了,那么EnsureCreated()不会更新数据库,也不会添加种子数据了。

  • 相关阅读:
    475. Heaters
    69. Sqrt(x)
    83. Remove Duplicates from Sorted List Java solutions
    206. Reverse Linked List java solutions
    100. Same Tree Java Solutions
    1. Two Sum Java Solutions
    9. Palindrome Number Java Solutions
    112. Path Sum Java Solutin
    190. Reverse Bits Java Solutin
    202. Happy Number Java Solutin
  • 原文地址:https://www.cnblogs.com/cgzl/p/9868501.html
Copyright © 2020-2023  润新知