先谈谈使用DB First踩的一些坑
版本冲突问题:
由于我们公司做的是HIS软件,HIS的功能很多业务很复杂,也就少不了会建很多张表、视图、存储过程什么的。我进公司前大家都自己更新模型,经常会遇到更新代码后编译报错。主要原因是模型更新后里面变动的东西太多了,大家又对这些变动的东西不熟悉,在遇到版本冲突的时候就按提示解决版本冲突,结果就导致了编译报错。最后统一由一个人负责更新模型。
更新模型时间长:
在更新时程序会检查每张表、每个字段、每个主键、每个索引逐一检查,更新一次模型基本上就是半个小时左右(简直蓝瘦)。
感觉DB First只适合那种表不多的中小型项目。
数据库升级脚本混乱
经常在生产库升级的时候遇到程序各种报错,各种数据库字类型和代码字段类型不一致、写的SQL脚本报错。
进入正题
废话不多说进入正题!先来一组命令
Enable-Migrations:启用迁移
Add-Migrations:为下次建议搭建基架(可以理解为将你写的模型生成SQL脚本,还有历史记录哦!强大不)
Update-Datebase:将代码变更同步数据库(可以理解为在数据库中执行上面生成的SQL)
Update-Datebase -Script -SourceMigrations $InitialDatabase:生成SQL脚本,能够从任意数据库版本升级。【这个很重要,特别是对生产环境中需要升级数据库】
什么?不知道这个命令怎么用?在哪用?那你一定用的不是VS Code,用VS的就在【工具】=》【Nuget包管理器】=》【程序包管理控制台】,别急着用哦!等我上代码先~
程序代码
/// <summary>
/// 定义模型
/// </summary>
public class Blog : BaseBlog
{
public int Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
[NotMapped]
public int Phone { get; set; }//存在NotMapped,字段将不会再数据库中创建
public char Char { get; set; }//char是数据关键字,在数据库中不会被创建
public DateTime? CreateTime { get; set; }
//public string NewColumn { get; set; }
}
/// <summary>
/// 定义模型规则
/// </summary>
public class BlogMap:EntityTypeConfiguration<Blog>
{
public BlogMap()
{
ToTable("Blogs");
HasKey(k => k.Id);
//Property(p => p.NewColumn).HasMaxLength(50);
}
}
public class EfDbContext : DbContext
{
public EfDbContext() : base("ConnectionString")
{
Database.SetInitializer(new DropCreateDatabaseAlways<EfDbContext>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//这坨代码很有用!!!定义模型规则代码可以分门别类维护,让上下文显得更简洁
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes().Where(type =>
type.BaseType != null && type.BaseType.IsGenericType &&
type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (var type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
base.OnModelCreating(modelBuilder);
}
public IDbSet<Blog> Blogs { get; set; }
}
配置文件代码
<connectionStrings>
<add name="ConnectionString" connectionString="Data Source=.;Initial Catalog=EfDb;User ID=sa;Integrated Security=true" providerName="System.Data.SqlClient"/>
</connectionStrings>
随便建个控制台程序,把上面代码贴进去就可以。
好戏开场,见证奇迹的时刻到了!
一、将模型同步到数据库
执行以下命令:
1、Enable-Migrations,看工程目录是不是已经生成了一些东西了。
2、Add-Migrations CreaateBg【按日期规则和定义的名称生成文件名】
3、Update-Datebase
到数据库看看是不是表结构已经创建好了
二、模型添加字段后同步到数据库
取消下面这行代码注释
public string NewColumn { get; set; }
1、Add-Migrations AddNewColumn【执行后再次生成一个变更文件】
2、Update-Datebase
现在数据库中已经加上了“NewColumn”这个字段了
三、修改数据库字段长度
取消下面这行代码注释
Property(p => p.NewColumn).HasMaxLength(50);
1、Add-Migrations EditColumnLength【执行后再次生成一个变更文件】
2、Update-Datebase
生成环境如何升级呢?
执行以下命令将生成的SQL能够让生产环境中的任何版本的数据库升级到最新版本
Update-Datebase -Script -SourceMigrations $InitialDatabase
总结
是不是感觉Code First很爽呢?只要你够熟练开发过程中都不用打开数据库,数据库的升级脚本也由开发环境自动生成好了。