Entity Framework Core知识小结

Entity Framework Core 创建上下文实例

我们在利用 Entity Framework Core 创建上下文实例的时候往往都是调用构造函数并重载 OnConfiguring 方法,这是 Entity Framework Core 默认的常用的创建上下文实例的方式。除了这种方式,微软也为我们准备了其他两种创建上下文实例的方式。算上常用的方式微软一共提供了三种创建上下文实例的方式,分别是:

  1. 直接调用上下文无参构造函数并重载 OnConfiguring 方法;
  2. 继承自上下文基类 DbContext 并传递 DbContextOptions 到上下文构造函数中;
  3. 使用依赖注入创建上下文实例。

上述三种方式总结起来就是两种创建上下文实例的方式,分别是 显示创建 和 通过依赖注入容器创建 。下面我分别来讲解这两种创建上下文实例的方式。

显示创建上下文实例

显示创建上下文实例是 Entity Framework Core 中常用的方式,当我们不需要通过依赖注入方式创建上下文实例的话就可以通过这种方式创建。

显示创建上下文实例最简单的方法是通过创建一个派生自 DbContext 的类,并且调用它的无参构造函数。代码如下:

        public class EFContext : DbContext
        {
            public EFContext(DbContextOptions options) : base(options)
            {
            }
        }

上述代码在运行时每次创建一个新的上下文实例都会调用 OnConfiguring 方法,这样我们可以通过利用 OnConfiguring 使用传递给上下文构造器或者其他实例的参数。这里需要注意的是每次调用上下文实例就必须使用 using 语句进行处理,也就是释放调用。

在 Entity Framework Core 中我们可以为每个上下文实例使用相同的 DbContextOptions 对象,这是因为 DbContext 构造函数可以接受 DbContextOptions 对象,它可以被显示调用可以通过它来隔离上下文。代码如下:

        public class EFContext : DbContext
        {
            public EFContext(DbContextOptions options) : base(options)
            {
            }
        }
        class Program
        {
            private static IServiceProvider serviceProvider;
            static void Main(string[] args)
            {
                DbContextOptions context = new DbContextOptionsBuilder().UseSqlServer("数据库连接字符串").Options;
                var services = new ServiceCollection().AddSingleton(context).AddScoped<EFContext>();
                serviceProvider = services.BuildServiceProvider();
            }
        }

上述代码中并没有进行重载 OnConfiguring 方法,但是在代码运行时 OnConfiguring 会被调用和重载,这时因为在进行注入上下文的时候会调用构造函数,还会对 OnConfiguring 进行调整。

依赖注入创建上下文实例

依赖注入上下文实例的方式有四种,分别是带无参构造函数的注入带 DbContextOptions 实例的构造函数注入使用泛型 DbContextOptions 注入使用 AddDbContext 或 AddDbContextPool 注入。下面我分别来讲一讲。

带无参构造函数的注入

使用带无参构造函数的注入DbContext 上下文派生类可以有一个无参数的构造函数并覆盖OnConfiguring方法。这样上下文类就没有任何依赖关系,这样除了上下文类型本身之外,其他任何内容都不需要在容器中注册。

带 DbContextOptions 实例的构造函数注入

使用带 DbContextOptions 实例的构造函数注入有时候需要在注入容器中注册 DbContextOptions 实例,将其注册为单例即可,这时我们只需要创建一次。下面我们以使用 DependencyInjection 为例来讲解一下,DependencyInjection 位于 Microsoft.Extensions.DependencyInjection 包中。代码如下:

        public class EFContext : DbContext
        {
            public EFContext(DbContextOptions options) : base(options)
            {
            }
        }
        
        class Program
        {
            private static IServiceProvider serviceProvider;
            static void Main(string[] args)
            {
                DbContextOptions context = new DbContextOptionsBuilder().UseSqlServer("数据库连接字符串").Options;
                var services = new ServiceCollection().AddSingleton(context).AddScoped<EFContext>();
                serviceProvider = services.BuildServiceProvider();
            }
        }

上述代码中通过 serviceProvider 将上下文注入容器中,DbContextOptions 实例也被注入到了构造函数中。

使用泛型 DbContextOptions 注入

使用泛型 DbContextOptions 注入有时我们需要注册多个 DbContext 上下文类,这时我们就可以使用泛型 DbContextOptions,代码如下:

        class Program
        {
            private static IServiceProvider serviceProvider;
            static void Main(string[] args)
            {
                DbContextOptions context1 = new DbContextOptionsBuilder().UseSqlServer("数据库连接字符串1").Options; 
                DbContextOptions context2 = new DbContextOptionsBuilder().UseSqlServer("数据库连接字符串2").Options; 
                var services = new ServiceCollection().AddSingleton(context1).AddScoped<EFContext1>().AddSingleton(context2).AddScoped<EFContext2>(); 
                serviceProvider = services.BuildServiceProvider();
            }
        }

代码在运行时会按照顺序逐个注入,也是是说当代码解析到 EFContext1 时会注入 DbContextOptions,解析到 EFContext2 时会注入 DbContextOptions

使用 AddDbContext 或 AddDbContextPool 注入

使用 AddDbContext 或 AddDbContextPool 注入使用 AddDbContext 或 AddDbContextPool 注入比较简单,只需要短短的几行代码即可:

        static void Main(string[] args)
        {
            var services = new ServiceCollection().AddDbContext<EFContext>(p => p.UseSqlServer("数据库连接字符串"));
        }

我们将 EFCoreDbContext 注册为 Scope,并将 DbContextOptions 通过委托构建为单例。委托继续使用与 OnConfiguring 中相同的 DbContextOptionsBuilder。Scope 是默认的注册类型,如果不想注册为 Scope 可以通过向 AddDbContext 传参来更改,但是要注意的是因为DbContext非线程安全,因此不可传递 Singleton。

写在最后

上面大致的讲了创建上下文实例的方式,不过是普通方式和通过注入的方式在大型的项目中必须通过充分的研究再决定使用哪种方式,因为这两种方式在不同的环境下都有可能引起性能问题。另外还需要注意上下文实例在使用之后必须进行释放处理,另外上下文实例可以被注入为 Scoped 类型和 Transient 类型,但是唯独不能注入为 Singleton 类型,因为 DbContext上下文是非线程安全的。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值