前言
EntityFramework Core 1.0 即原来的EF7.0更名,从.Net Framework平台向.Net Core平台的更新.
吐槽一下,既然.Net Framework更名为.Net Core的话,EntityFramework为啥不更名为EntityCore,弄得名字越来越长,多打9个字母也累啊.
官方资料
项目地址:https://github.com/aspnet/EntityFramework
官方文档:https://docs.efproject.net/en/latest/platforms/coreclr/index.html
关于本笔记
本笔记会以Ubuntu平台开发,数据库采用多种数据库(包括Sqlite,SQL Server和Npgsql),并在Github上提供源码.
为了纯粹学习EntityFramework Core(以下简称EFCore),代码将以Console形式开发,剥离掉ASP.NET等部分.
开始之前,先下载所需要的包
- .Net Core安装参考:http://www.jianshu.com/p/36c601d27efa
- Sqlite的Ubuntu驱动:
$ sudo apt-get install libsqlite3-dev
关于本篇
本篇将简单构建一个EFCore应用程序,并插入一条数据。
创建EFCore Console项目
$ dotnet new
Created new C# project in /home/yotsuki/code/EFCoreLearn/learn01.
修改配置文件
在project.json的dependencies节点中加入引用,
"Microsoft.EntityFrameworkCore": "1.0.0-rc2-final",
"Microsoft.EntityFrameworkCore.Sqlite": "1.0.0-rc2-final",
"Microsoft.EntityFrameworkCore.Tools": {
"type":"build",
"version": "1.0.0-preview1-final"
},
并在framework中加入"portable-net452+win81"
"frameworks": {
"netcoreapp1.0": {
"imports": ["dnxcore50","portable-net452+win81"]
}
},
这里我们先用Sqlite为例子,修改完成后,输入命令
$ dotnet restore
将自动下载所需要的包,如果是第一次下载,会比较慢,请耐心等待
添加一个DbContext
新建一个文件SqliteContext.cs
using Microsoft.EntityFrameworkCore;
public class SqliteContext:DbContext
{
public SqliteContext():base(){}
public SqliteContext(DbContextOptions<SqliteContext> options) : base(options) { }
}
我们在使用EF6.x的时候,DbContext默认会读取App.config/Web.config中配置的同名连接字符串。但在EFCore中并不如此。由于.NET Core是一个真正模块化的平台,读取配置文件也需要自己去引用包。
这里我先按照官方文档中提供的方法写入连接字符串
调用前传入
var builder = new DbContextOptionsBuilder<SqliteContext>();
builder.UseSqlite("Filename=./learn01.db");
using (var context = new SqliteContext(builder.Options)) {
//...
}-
重写DbContext的OnConfiguring方法
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlite("Filename=./learn01.db"); }
添加一个实体
新建一个实体类User.cs
public class User
{
public Guid ID { get; set; }
public string Name { get; set; }
public string Password { get; set; }
}
并将实体加入SqliteContext中
public DbSet<User> Users { get; set; }
添加迁移
迁移功能(Migration)在EF6.x已经有了,CodeFirst开发中迁移功能可以方便的进行数据库模型的变更。
在EF6.x中,Sqlite的驱动并不支持迁移,通常我们需要自己去写一个迁移功能。但这次EFCore提供的Sqlite驱动已经能够进行迁移了。
要使用迁移功能需要先在project.json中添加工具支持
"tools": {
"Microsoft.EntityFrameworkCore.Tools": {
"imports": [ "portable-net451+win8" ],
"version": "1.0.0-preview1-final"
}
},
再restore后就可以使用命令了
$ dotnet restore
$ dotnet ef -h
使用migrations add命令来添加迁移
$ dotnet ef migrations add Init
Project learn01 (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
Done. To undo this action, use 'ef migrations remove'
此命令对应EF6.x的Add-Migration命令
添加迁移完成后,会在项目目录中新建一个Migrations目录和相应的迁移类
和EF6.X一样,AddMigration之后需要update才会体现到数据库中
$ dotnet ef database update
Project learn01 (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
Applying migration '20160526075826_Init'.
Done.
完成迁移,我们来看下数据库
数据库生成在bin/Debug/netcoreapp1.0/ 目录下
其中包含两个表,“Users”和"__EFMigrationsHistory"表。“Users”不用多说,就是我们添加的实体表。
"__EFMigrationsHistory"是迁移记录表,查询一下可以看到,其中已经有了一条数据,对应着我们本次的迁移。
EFCore的迁移记录相对与EF6.x简单了一些,这里我推断EFCore并没有根据Model改变的一些操作。
下图是EF6.1.2的迁移记录表,对比一下就发现目前EFCore的设计更加纯粹
简单的添加一条记录
接下来,我们要为数据库添加第一条记录
我们修改Program.cs
public static void Main(string[] args)
{
using (var context = new SqliteContext()) {
context.Users.Add(new User(){ Name="yotsuki",Password="123456"});
var result = context.SaveChanges();
if (result > 0) {
Console.WriteLine("1 row installed.");
}else {
Console.WriteLine("install failed.");
}
}
}
然后运行命令
$ dotnet build
$ dotnet run
Project learn01 (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
1 row installed.
我们再看下数据库
一条数据已插入(Guid因为是二进制存储,显示有一些问题)
其他数据库
Sql Server
在project.json添加引用
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.0-rc2-final",
在OnConfiguring方法中修改
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(/*连接字符串*/);
}
Npgsql
在project.json添加引用
"Npgsql.EntityFrameworkCore.PostgreSQL": "1.0.0-rc2-final",
在OnConfiguring方法中修改
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql(/*连接字符串*/);
}