好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Entity Framework Core - DbContext配置和初始化

在将数据移入和移出数据库时,重要的是要跟踪所做的更改。 否则,该数据将不会被写回到数据库中。 同样,您必须插入创建的新对象并删除所有删除的对象。

您可以 随着对象模型的每次更改来更改数据库,但是这可能导致许多非常小的数据库调用,这最终会非常缓慢 。 此外,它要求您为整个交互打开一个 事务 ,如果您的业务事务跨越多个请求,则这是不切实际的。 如果您需要跟踪已读取的对象,从而避免不一致的读取,则情况甚至更糟。

工作单元会跟踪您在业务交易过程中可能影响数据库的所有操作。完成后,它会计算出由于工作而需要更改数据库的所有工作。英文原文请参考:EAA的P。

  EF Core的典型工作单元包括(重点理解这段,有助于我们对EF Core工作原理的理解):

创建DbContext实例 根据上下文跟踪实体实例。实体将在以下情况下被追踪 正在从查询返回 正在添加或附加到上下文 根据需要对所跟踪的实体进行更改以实现业务规则 调用SaveChanges或SaveChangesAsync。EF Core检测所做的更改,并将这些更改写入到数据库 释放DbContext

   重要知识点:

使用后释放DbContext非常重要。这可确保释放所有非托管资源,并注销任何事件或其他挂钩,以防止在实例保持引用时出现内存泄漏。 DbContext不是线程安全的。不要在线程间共享上下文。请确保在继续使用上下文实例之前,等待所有异步调用。 EF Core引发的InvalidOperationException可以使上下文进入不可恢复状态。

ASP.NET Core 依赖关系注入中的 DbContext

   在许多 Web 应用程序中,每个 HTTP 请求都对应于单个工作单元。  这使得上下文生存期与请求的生存期相关。

   使用依赖关系注入配置 ASP.NET Core 应用程序。  可以使用  Startup.cs  的  ConfigurureServices  方法中的 AddDbContext 将 EF Core 添加到此配置。  例如:

 public   void   ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    
    services.AddDbContext <ApplicationDbContext> (
        options  => options.UseSqlServer( "  name=ConnectionStrings:DefaultConnection  "  ));
} 

   此示例将名为  ApplicationDbContext  的  DbContext  子类注册为 ASP.NET Core 应用程序服务提供程序(也称为  依赖关系注入容器)中的作用域服务。 

   options => options.UseSqlServer    上下文配置为使用 SQL Server 数据库提供程序,
  "name=ConnectionStrings:DefaultConnection"表示   将从 ASP.NET Core 配置读取连接字符串。  在  ConfigureServices  中的何处调用  AddDbContext  通常不重要。    

   ApplicationDbContext  (数据库上下文)类必须公开具有  DbContextOptions<ApplicationDbContext>  参数的公共构造函数。  这是将  AddDbContext  的上下文配置传递到  DbContext  的方式。  例如:

 public   class   ApplicationDbContext : DbContext
{
      public  ApplicationDbContext(DbContextOptions<ApplicationDbContext>  options)
        :   base  (options)
    {
    }
} 

   然后, ApplicationDbContext  可以通过构造函数注入在 ASP.NET Core 控制器或其他服务中使用。  例如:

 1   public   class   MyController
  2   {
  3       private   readonly   ApplicationDbContext _context;
  4  
 5       public   MyController(ApplicationDbContext context)
  6       {
  7          _context =  context;
  8       }
  9  }

  最终结果是为每个请求创建一个  ApplicationDbContext  实例,并传递给控制器,以在请求结束后释放前执行工作单元。

使用“new”的简单的 DbContext 初始化

   可以按照常规的 .NET 方式构造  DbContext  实例,例如,使用 C# 中的  new 。  可以通过重写  OnConfiguring  方法或通过将选项传递给构造函数来执行配置。  例如:

 1   public   class   ApplicationDbContext : DbContext
  2   {
  3       protected   override   void   OnConfiguring(DbContextOptionsBuilder optionsBuilder)
  4       {
  5          optionsBuilder.UseSqlServer( @"  Server=(localdb)\mssqllocaldb;Database=Test  "  );
  6       }
  7  }

   通过此模式,还可以轻松地通过  DbContext  构造函数传递配置(如连接字符串)。  例如:

  1   public   class   ApplicationDbContext : DbContext
   2   {
   3       private   readonly   string   _connectionString;
   4  
  5       public  ApplicationDbContext( string   connectionString)
   6       {
   7          _connectionString =  connectionString;
   8       }
   9  
 10       protected   override   void   OnConfiguring(DbContextOptionsBuilder optionsBuilder)
  11       {
  12           optionsBuilder.UseSqlServer(_connectionString);
  13       }
  14  }

   或者,可以使用  DbContextOptionsBuilder  创建  DbContextOptions  对象,然后将该对象传递到  DbContext  构造函数。  这使得为依赖关系注入配置的  DbContext  也能显式构造。  例如,使用上述为 ASP.NET Core 的 Web 应用定义的  ApplicationDbContext  时:

 1   public   class   ApplicationDbContext : DbContext
  2   {
  3       public  ApplicationDbContext(DbContextOptions<ApplicationDbContext>  options)
  4          :  base  (options)
  5       {
  6       }
  7  }

  可以创建  DbContextOptions ,并可以显式调用构造函数:

 var  contextOptions =  new  DbContextOptionsBuilder<ApplicationDbContext> ()
    .UseSqlServer(  @"  Server=(localdb)\mssqllocaldb;Database=Test  "  )
    .Options;

  using   var  context =  new  ApplicationDbContext(contextOptions);

使用 DbContext 工厂(例如对于 Blazor)

   某些应用程序类型(例如 ASP.NET Core Blazor)使用依赖关系注入,但不创建与所需的  DbContext  生存期一致的服务作用域。  即使存在这样的对齐方式,应用程序也可能需要在此作用域内执行多个工作单元。  例如,单个 HTTP 请求中的多个工作单元。 在这些情况下,可以使用 AddDbContextFactory 来注册工厂以创建  DbContext  实例。  例如:

 1   public   void   ConfigureServices(IServiceCollection services)
  2   {
  3      services.AddDbContextFactory<ApplicationDbContext>(options =>
 4          options.UseSqlServer( @"  Server=(localdb)\mssqllocaldb;Database=Test  "  ));
  5  }

   ApplicationDbContext  类必须公开具有  DbContextOptions<ApplicationDbContext>  参数的公共构造函数。  此模式与上面传统 ASP.NET Core 部分中使用的模式相同。

 1   public   class   ApplicationDbContext : DbContext
  2   {
  3       public  ApplicationDbContext(DbContextOptions<ApplicationDbContext>  options)
  4          :  base  (options)
  5       {
  6       }
  7  }

   然后,可以通过构造函数注入在其他服务中使用  DbContextFactory  工厂。  例如:

 1   private   readonly  IDbContextFactory<ApplicationDbContext>  _contextFactory;
  2  
 3   public  MyController(IDbContextFactory<ApplicationDbContext>  contextFactory)
  4   {
  5      _contextFactory =  contextFactory;
  6  }

   然后,可以使用注入的工厂在服务代码中构造 DbContext 实例。  例如:

 1   public   void   DoSomething()
  2   {
  3       using  ( var  context =  _contextFactory.CreateDbContext())
  4       {
  5           //   ... 
 6       }
  7  }

  请注意,以这种方式创建的  DbContext  实例并非由应用程序的服务提供程序进行管理,因此 必须由应用程序释放。

DbContextOptions

   所有  DbContext  配置的起始点都是 DbContextOptionsBuilder。  可以通过三种方式获取此生成器:

在  AddDbContext  和相关方法中 在  OnConfiguring  中 使用  new  显式构造

   上述各节显示了其中每个示例。  无论生成器来自何处,都可以应用相同的配置。  此外,无论如何构造上下文,都将始终调用  OnConfiguring 。  这意味着即使使用  AddDbContext , OnConfiguring  也可用于执行其他配置。

 

配置数据库提供程序

   每个  DbContext  实例都 必须配置为使用一个且仅一个数据库提供程序。  ( DbContext  子类型的不同实例可用于不同的数据库提供程序,但单个实例只能使用一个。) 使用特定的  Use* " 调用配置数据库提供程序。  例如,若要使用 SQL Server 数据库提供程序:

 1   public   class   ApplicationDbContext : DbContext
  2   {
  3       protected   override   void   OnConfiguring(DbContextOptionsBuilder optionsBuilder)
  4       {
  5          optionsBuilder.UseSqlServer( @"  Server=(localdb)\mssqllocaldb;Database=Test  "  );
  6       }
  7  }

   这些  Use* " 方法是由数据库提供程序实现的扩展方法。  这意味着必须先安装数据库提供程序 NuGet 包,然后才能使用扩展方法。

   EF Core 数据库提供程序广泛使用扩展方法。  如果编译器指示找不到方法,请确保已安装提供程序的 NuGet 包,并且你在代码中已有  using Microsoft.EntityFrameworkCore; 。

  下表包含常见数据库提供程序的示例:

数据库系统

配置示例

NuGet 程序包 SQL Server 或 Azure SQL .UseSqlServer(connectionString) Microsoft.EntityFrameworkCore.SqlServer Azure Cosmos DB .UseCosmos(connectionString, databaseName) Microsoft.EntityFrameworkCore.Cosmos SQLite .UseSqlite(connectionString) Microsoft.EntityFrameworkCore.Sqlite EF Core 内存中数据库 .UseInMemoryDatabase(databaseName) Microsoft.EntityFrameworkCore.InMemory PostgreSQL* .UseNpgsql(connectionString) Npgsql.EntityFrameworkCore.PostgreSQL MySQL/MariaDB* .UseMySql((connectionString) Pomelo.EntityFrameworkCore.MySql Oracle* .UseOracle(connectionString) Oracle.EntityFrameworkCore

避免 DbContext 线程处理问题

   Entity Framework Core 不支持在同一  DbContext  实例上运行多个并行操作。  这包括异步查询的并行执行以及从多个线程进行的任何显式并发使用。  因此,始终立即  await  异步调用,或对并行执行的操作使用单独的  DbContext  实例。

  当 EF Core 检测到尝试同时使用  DbContext  实例的情况时,你将看到  InvalidOperationException

 

 

Entity Framework Core - DbContext配置和初始化

标签:cat   个数   异步查询   style   sqli   memory   ora   注销   exce   

查看更多关于Entity Framework Core - DbContext配置和初始化的详细内容...

  阅读:35次

上一篇: Java - Java 连接 SQL

下一篇:sql小练习