我在网上找了半天,居然没有一篇文章说过这个,基本上都是在 Core上使用EntityFrameoworkCore的教程。当我看到EFCore使用的.NET Standard 开发的时候,我就知道这东西可以在Framework上跑,所以我做了一个实验,然后分享给大家。
环境必须是 .NET Framework 4.6.1+,因为 EF Core是基于.NET Standard 2.0 开发。
EF Core 只支持 Code First 模式。
首先下载安装包
- :核心包,不多说
- :支持 PS 命令的 Code First 工具包
- :Code First 必备包
下面的包是自定义数据驱动的包,想要啥自己去Nuget上找就对了
- :Sql Server 驱动
- :Sqlite 驱动
其他的自己去nuget上找吧!我这里以 Sql Server 为例子。
开始使用
-
首先我先声明1个实体,User,这个不多说,和以前用法一样
[Table("Users")] class User { [Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [Required,StringLength(30)] public string Name { get; set; } public int Age { get; set; } }
-
一样是需要继承 DbContext 基类。
class MyDbContext : DbContext { public DbSet<User> Users { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("Data source=.;Initial Catalog=EFCoreFramework;Trusted_Connection=true"); } }
在 EF Core 中,需要重写 OnConfiguring 方法,然后写连接字符串以及要使用的驱动。
在EF中的连接字符串,我们是这样写的
public class MyDbContext : DbContext { public MyDbContext() : base("connectionString"){ } }
这是两者的不同,不要搞错了
-
添加迁移
EF Core 中不需要启用 Enable-Migration 命令,直接 “Add-Migration 给一个名称” 即可。
你会看到生成的迁移脚本大致是这样的
public partial class init : Migration { protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable( name: "Users", columns: table => new { Id = table.Column<int>(nullable: false) .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), Name = table.Column<string>(nullable: true) }, constraints: table => { table.PrimaryKey("PK_Users", x => x.Id); }); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( name: "Users"); } }
-
更新数据库
Update-Database 更新数据库
与曾经操作EF一样的方式来操作
using (var context = new MyDbContext())
{
context.Users.Add(new User { Name = "张三" });
context.SaveChanges();
var list = context.Users.ToList();
list.ForEach(item =>
{
Console.WriteLine($"{}:{}");
});
}
是不是很简单呢?
使用依赖注入模式操作
现在到处都充斥着IoC的方式来设计程序,不可能向上面那样总实例化一个 DbContext 来操作,而且一般使用驱动的方式也会在注入时才会选择,而不是写在 DbContext 中的。
- 更改 MyDbContext 的内容
class MyDbContext : DbContext { public MyDbContext(DbContextOptions<MyDbContext> options) : base(options) { } public DbSet<User> Users { get; set; } }
使用了 DbContextOptions
来配置 EF Core,这种方式叫 DesignTime 。所以我们需要实现IDesignTimeDbContextFactory<TContext>
接口来支持 Code First 的设计模式,否则会在添加迁移的时候报以下异常:
>Unable to create an object of type ‘MyDbContext’. Add an implementation of ‘IDesignTimeDbContextFactory’ to the project, or see /fwlink/?linkid=851728 for additional patterns supported at design time.
```csharp
class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{
public MyDbContext CreateDbContext(string[] args)
{
var dbBuilder = new DbContextOptionsBuilder<MyDbContext>();
();
var option = ;
return new MyDbContext(option);
}
}
```
**当然你也可以有多个 `DbContextFactory`,记得在添加迁移的时候指定一个就行了。**
- 安装 Autofac
这仅仅是一个常用的依赖注入工具,而且是目前最常用的。当然你也可以选择其他的比如 Unity 或者 等等
我用了一个 Service 类,把 MyDbContext 注入进去,然后来进行一个简单的操作:
class Service
{
MyDbContext _context;
public Service(MyDbContext context)
{
_context = context;
}
public void Create()
{
_context.Users.Add(new User { Name = "inject name", Age = 12 });
_context.SaveChanges();
var list = _context.Users.ToList();
list.ForEach(item =>
{
Console.WriteLine($"{}:{}");
});
}
}
然后来看 Autofac 的配置。
var builder = new ContainerBuilder();
builder.Register(m=>new MyDbContextFactory().CreateDbContext(null)).As<MyDbContext>();
builder.RegisterType<Service>();
var container = builder.Build();
//后面的 mvc或 webapi 怎么注入请参考官方教学
我这里进行一个模拟调用
var service = container.Resolve<Service>();
service.Create();
数据成功写入,证明依赖注入是成功滴。