使用CodeFirst创建并更新数据库

创建数据库

首先创建一个控制台项目,安装 EntityFrame 并在项目中添加实体类和上下文。其中 ConnStr 表示配置文件中连接字符串的名字,DbContext 根据 DbSet 属性的类型来创建数据表

internal class Student
{
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual Grade Grade { get; set; }
}

internal class Grade
{
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual List<Student> Students { get; set; }
}

internal class MyDBContext : DbContext
{
    public MyDBContext() : base("name=ConnStr")
    {

    }
    public virtual DbSet<Grade> Grades { set; get; }
}

配置文件配置如下,其中 entityFramework SqlClient 相关是安装 EntityFrame 时自动配好的,我们需要添加 connectionString 为 自己的数据库链接

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
  </startup>
  <entityFramework>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
	<connectionStrings>
		<add name="ConnStr" connectionString="initial catalog=Test0424;data source=.;user id=sa;password=Aa123456" providerName="System.Data.SqlClient"/>
	</connectionStrings>
</configuration>

最后在 Main 方法中调用 DbSet 数据,启动程序就能看到在本地数据库中生成了 Grade Student 表,虽然我们没有为 DbContext 添加 Student 类型的 DbSet ,但依然创建了 Student 表,这是因为在 Grade 中定义了关联属性 Students

        static void Main(string[] args)
        {
            using(MyDBContext context = new MyDBContext())
            {
                Grade grade = context.Grades.FirstOrDefault();
            }
        }

如果运行过程中报以下的错误,说明在实体类中没有设置 主键 ,EntityFramework会默认把属性名为 Id 的属性设置为主键,如果要指定别的字段为主键需要使用特性 [Key] ,需要注意的是应该定义为属性而不是字段

"EntityType 'Grade' has no key defined. Define the key for this EntityType.Grade: EntityType: EntitySet 'Grade' is based on type 'Grade' that has no keys defined." 

 

修改数据库

现在给 Student 类添加 Age 字段

internal class Student
{
    public int Id { get; set; }

    public string Name { get; set; }

    public int Age { get; set; }

    public virtual Grade Grade { get; set; }
}

再次运行 Main 方法,报以下的错误,说明实体类在创建后已经被修改了,需要对数据库进行更新

“The model backing the 'MyDBContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).”

1、首先打开 程序包管理控制台

2、输入 Enable-Migrations ,得到以下输出结果并发现在项目下多了一个 Migrations 文件夹,输出结果的大概意思就是如果要使用 自动迁移 ,需要删除 Migrations文件夹 并重新运行Enable-Migrations,并指定 EnableAutomaticMigrations 参数。在启用自动迁移之后,我们再修改实体文件,只需执行 Update-Database 命令即可完成对数据库的更新

InitialCreate文件:因为我们事先让 Code First 自动创建了一个数据库,这个迁移文件中的代码表示数据库中已创建的对象。文件名包含时间戳,如果尚未创建数据库,则不会将此 InitialCreate 迁移添加到项目中,在调用 Add-Migration 时,InitialCreate 文件创建表的代码将为新迁移搭建基架

Configuration文件 :我们可以在此文件中针对上下文配置迁移行为

3、启用迁移之后,继续输入 Update-Database 命令来更新数据库

通过上面的提示信息我们可以知道,要想更新数据库需要启用 自动迁移 或者使用 Add-Migration命令来创建迁移文件

4、在控制台输入 Add-Migration MigrationName ,运行得到以下输出结果并发现在 Migrations 文件夹中多了一个时间戳加迁移名称的文件

 5、打开 MigrationName 文件,得到以下代码。在迁移文件中描述了迁移需要进行的操作,因此我们也可以直接修改迁移文件而不用修改实体类

public partial class MigrationName : DbMigration
{
    /// <summary>
    /// 这是一个覆盖方法,表示迁移的“上升”操作,即在数据库中应用迁移时要执行的操作
    /// </summary>
    public override void Up()
    {
        //AddColumn方法用于向名为“Students”的数据库表中添加一个名为“Age”的列,其数据类型为整数,并且指定该列不允许为空。
        //"dbo.Students"表示数据库中的表,"Age"表示要添加的列名,c => c.Int(nullable: false)表示列的数据类型为整数且不允许为空
        AddColumn("dbo.Students", "Age", c => c.Int(nullable: false));
    }

    /// <summary>
    /// 这是另一个覆盖方法,表示迁移的“下降”操作,即在需要撤销迁移时要执行的操作
    /// </summary>
    public override void Down()
    {
        //DropColumn方法用于从名为“Students”的数据库表中删除名为“Age”的列。"dbo.Students"表示数据库中的表,"Age"表示要删除的列名
        DropColumn("dbo.Students", "Age");
    }
}

6、最后在程序包管理器控制台输入 Update-Database ,也可以使用 Update-Database -Verbose 命令,该命令可以使我们看到SQL语句的执行过程,得到以下输出结果,并且刷新数据库发现修改已经迁移进来

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值