我的EF学习笔记是按照 汪鹏(网名Jeffcky) 大侠《你必须掌握的Entity Framework 6.x与Core 2.0》来弄的。
这也是我第一篇博客,感觉这东西不能乱写啊,算了,干吧。
EF我之前是做过的,但是只是一些零碎的东西,不成系统。
EF是什么呢?ORM框架object renational mapping 对象关系映射,下面我就用自己的话来了。
数据库里面存放数据用表,而我们程序代码使用类,一个是数据世界的弄法,一个是对象世界的弄法。EF就是为我们做这种对象映射的处理,让我可以不用关心数据库,只关系类 怎么设计就行了。
我说完了。它主要就是这个对吧,当然会有其他的很多东西,通过程序直接创建数据库,然后更多的精力放到了类上,业务逻辑上,突然多出来的精力没处使,是不是就弄出了什么领域驱动设计?
现在来创建一个控制台程序,安装EF,打开程序包管理控制台输入命令:install-package entityframework
创建Blog类,写一个EFDbContext类,这个类派生自DbContext,为blog公开一个DbSet属性
然后在main方法里面实例化上下文对象,添加一个blog实例,接着查询这个实例,打印出来
然后控制台大概过了十多秒,看到了刚刚添加的数据,那么简单的创建数据库、表就完了~
1
2
3
4
5
6
7
8
9
10
11
12
13
|
namespace _20190105 { // 此上下文是与数据库交互的一个中间桥梁,可以称之为会话,为每一个模型公开一个DbSet<>,定义DbSet有三种方式 public class EFDbContext:DbContext { // DbSet 三种设计方式,不太懂,我随便弄了一种 //public DbSet<Blog> Blog { get; set; } //public IDbSet<Blog> Blog { get; set; } public DbSet<Blog> Blog { get { return Set<Blog>(); } } } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
namespace _20190105 { class Program { static void Main( string [] args) { // 上下文实例化,添加一个blog实例 using (EFDbContext db = new EFDbContext()) { db.Blog.Add( new Blog { CreatedTime = DateTime.Now, Double = 11.11, Float = 2.2f, ID = 1, Name = "第er篇博客" , Url = "http://localhost:8080" }); db.SaveChanges(); Console.WriteLine(JsonConvert.SerializeObject(db.Blog.ToList())); } } } } |
来看看数据库,对照着模型看一下,数据库和表是什么样子的。这里要注意一点,如果是按照上面的几步操作,EF默认会给我们把数据库创建到localdb里面
localdb是个什么玩意,他也是个数据库,但是这和我们SQL server数据库管理工具创建的数据库有什么不一样呢?网上说这个localdb完全是为了针对开发人员使用的,一个数据库最大容量为10G,那他到底是在安装VS的时候安装的,还是在装SQLserver安装的呢?
要查看刚刚创建的数据库,在VS上点击“视图”-->"SQL server数据库对象资源管理器",也可以通过SQL server去连接它
通过SQL server管理工具连接到这个localdb,有可能你的机器上没有安装这个localdb,我这个没有刻意去安装,反正就是有这个东西
首先,数据库创建在localdb里面,数据库的名称是我们项目命名空间+上下文类名
然后我们看表名,我们的DbSet<>属性是Blog,但是在数据库里面表明成了Blogs,变成复数形式了
然后我们看字段,ID默认给我弄成了主键,并且设置为自增长
string类型对应nvarchar(max),并且允许为空
double类型对应float
float类型对应real
datetime?可空类型对应datetime,可空
刚刚我添加一个条数据,ID为1,现在我又添加一个blog实例,ID还是1,但是没有报错,正确插入进去了,ID自增长为2
然后我在Blog中添加一个字段Test,再次运行,报错
未经处理的异常: System.InvalidOperationException: The model backing the 'EFDbContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
他说没有在程序集中发现迁移配置类型,可以使用enable-migrations添加配置
就是说要用这个迁移,要先执行 enable-migrations 命令来开启一下迁移,这些命令不区分大小写
我执行了命令:enable-migrations 发现我的项目中被创建了一个Migrations文件夹,里面有两个文件
但是我并没有看到刚刚添加的那个Test属性,先不管,我们直接更新看看
输入命令:update-database
然后他说没有挂起的显示迁移,什么意思,不就是说没什么可以更新的吗?
然后我再次生成一个新的迁移类文件,输入命令:add-magration jinshantest 这个jinshantest就是你为这个迁移文件取的一个名字
现在就有了。
那么现在就更新到数据库里面吧,现在我们再来执行迁移:update-database -verbose 加上-verbose就是显示迁移的详细信息
可以看到它根据迁移文件的内容,生成了创建列的SQL语句,并更新到了数据库
改动了模型就要做数据迁移,继续add-migration jinshantest2 生成迁移文件
可以的,他生成的SQL语句是下面这样的。
ALTER TABLE [dbo].[Blogs] ADD [Test2] [nvarchar](max) NOT NULL DEFAULT ''
然后修改我们的Dbcontext文件,告诉EF我们的数据库连接字符串
于是我运行程序,报错了:找不到对象“dbo.Blogs”
我检查我的的SQL server 里面什么都没有。
难道是因为我Main方法里有做数据持久化的代码,他在插入数据的时候找不到表,就报错了?
刚刚在localDB里面不是好好的吗?在对localDB操作的时候,我什么都没做,他自动给我创建数据库,创建表
难道我现在还要在SQL server中创建一个数据库然后创建一个表?那要你做什么?
行,我弄了下,大概知道了,我要先做数据迁移才行,就是把刚刚的那些迁移文件现在针对我的SQL server执行,于是命令行输入:update-database -verbose
行了,数据库和表都有了。
SQLserver 和localDB就是这一点区别,localDB不用先迁移。
后面还有其他的很多配置,不过总算是能够简单地创建数据库和表了,并且修改model后,我们利用数据迁移对数据库做更新,还是比较完整吧。
书中的内容都是一点点讲起的,数据迁移在后面才会讲到。书有目录啊,必须跟着目录走啊。我自己随便弄,还是觉得要用一个完整的东西把这些散碎的东西串起来好一些。