您的位置:首页 > 其它

在 .NET Framework 上使用 EntityFrameworkCore

2018-01-24 13:08 357 查看
我在网上找了半天,居然没有一篇文章说过这个,基本上都是在ASP.NET Core上使用EntityFrameoworkCore的教程。当我看到EFCore使用的.NET Standard 开发的时候,我就知道这东西可以在Framework上跑,所以我做了一个实验,然后分享给大家。

环境必须是 .NET Framework 4.6.1+,因为 EF Core是基于.NET Standard 2.0 开发。

EF Core 只支持 Code First 模式。

首先下载安装包

Microsoft.EntityFrameworkCore:核心包,不多说

Microsoft.EntityFrameworkCore.Tool:支持 PS 命令的 Code First 工具包

Microsoft.EntityFrameworkCore.Design:Code First 必备包

下面的包是自定义数据驱动的包,想要啥自己去Nuget上找就对了

Microsoft.EntityFrameworkCore.SqlServer:Sql Server 驱动

Microsoft.EntityFrameworkCore.Sqlite: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($"{item.Id}:{item.Name}");
});
}


是不是很简单呢?

使用依赖注入模式操作

现在到处都充斥着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 https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.

class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{
public MyDbContext CreateDbContext(string[] args)
{
var dbBuilder = new DbContextOptionsBuilder<MyDbContext>();
dbBuilder.UseSqlServer(Program.connectionString);
var option = dbBuilder.Options;
return new MyDbContext(option);
}
}


当然你也可以有多个
DbContextFactory
,记得在添加迁移的时候指定一个就行了。


安装 Autofac

这仅仅是一个常用的依赖注入工具,而且是目前最常用的。当然你也可以选择其他的比如 Unity 或者 Sprint.Net 等等

我用了一个 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($"{item.Id}:{item.Name}");
});
}
}


然后来看 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();


数据成功写入,证明依赖注入是成功滴。

欢迎任何拍砖!!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: