在 .NET Framework 上使用 EntityFrameworkCore

我在网上找了半天,居然没有一篇文章说过这个,基本上都是在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接口来支持 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.

```csharp
   class MyDbContextFactory : IDesignTimeDbContextFactory
   {
       public MyDbContext CreateDbContext(string[] args)
       {
           var dbBuilder = new DbContextOptionsBuilder();
           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();

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

欢迎任何拍砖!!

你可能感兴趣的:(ASP.NET,Core)