ASP.NET 核心 – DBContext

ASP.NET 核心 – DBContext


实体框架使您能够使用称为实体的公共语言运行时 (CLR) 对象查询、插入、更新和删除数据。实体框架将模型中定义的实体和关系映射到数据库。它还提供设施 –

  • 将从数据库返回的数据具体化为实体对象。

  • 跟踪对对象所做的更改。

  • 处理并发。

  • 将对象更改传播回数据库。

  • 将对象绑定到控件。

负责将数据作为对象进行交互的主要类是 DbContext。使用上下文的推荐方法是定义一个派生自 DbContext 的类,并公开表示上下文中指定实体集合的 DbSet 属性。

数据库上下文

从逻辑上讲,DBContext 映射到具有 DBContext 理解的架构的特定数据库。在该 DBContext 类上,您可以创建类型为 DbSet<T> 的属性。泛型类型参数 T 将是一种实体类型,例如 Employee 是 FirstAppDemo 应用程序中的一个实体。

例子

让我们举一个简单的例子,我们将在其中创建一个 DbContext 类。在这里,我们需要在 Models 文件夹中添加一个新类并将其命名为FirstAppDempDbContext尽管这个类本身不是一个模型,但它确实将我们所有的模型放在一起,以便我们可以将它们与数据库一起使用。

FirstAppDemo 上下文

从 Miscrosoft.Data.Entity 命名空间中的 DbContext 类继承您的上下文类。现在在该类上实现 Employee 的 DbSet。

每个 DbSet 将映射到数据库中的一个表。如果您有一个属性 DbSet 的员工,并且该属性的名称是员工,则实体框架将默认在您的数据库中查找员工表。

using FirstAppDemo.Models; 
using Microsoft.Data.Entity; 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks;  

namespace OdeToFood.Models { 
   public class FirstAppDemoDbContext : DbContext { 
      public DbSet<Employee> Employees { get; set; } 
   } 
} 

实现非常简单,因为我们只有一个模型可以使用。我们只需要一个属性,即EmployeeDbSet,我们可以将此属性命名为Employees

现在让我们将这个类直接插入到控制器中,然后控制器可以使用FirstAppDemoDbContext来查询数据库。我们将通过向 HomeController 类添加一个新类来简化所有这些,在该类中我们实现了添加员工和获取员工的方法,如下面的程序所示。

using Microsoft.AspNet.Mvc; 

using FirstAppDemo.ViewModels; 
using FirstAppDemo.Services; 
using FirstAppDemo.Entities; 
using FirstAppDemo.Models; 

using System.Collections.Generic; 
using System.Linq;  

namespace FirstAppDemo.Controllers { 
   public class HomeController : Controller { 
      public ViewResult Index() { 
         var model = new HomePageViewModel(); 
         
         using (var context = new FirstAppDemoDbContext()) { 
            SQLEmployeeData sqlData = new SQLEmployeeData(context); 
               model.Employees = sqlData.GetAll(); 
         }  
         return View(model); 
      } 
   }  
   public class SQLEmployeeData { 
      private FirstAppDemoDbContext _context { get; set; } 
      public SQLEmployeeData(FirstAppDemoDbContext context) { 
         _context = context;
      } 
      public void Add(Employee emp) { 
         _context.Add(emp); 
         _context.SaveChanges(); 
      } 
      public Employee Get(int ID) { 
         return _context.Employees.FirstOrDefault(e => e.Id == ID); 
      } 
      public IEnumerable<Employee> GetAll() { 
         return _context.Employees.ToList<Employee>(); 
      } 
   } 
   public class HomePageViewModel { 
      public IEnumerable<Employee> Employees { get; set; } 
   } 
}   

在上面的 SQLEmployeeData 类中,您可以看到我们定义了 Add 方法,该方法将向上下文添加一个新员工对象,然后保存更改。在 Get 方法中,它将根据 ID 返回一个员工。而在 GetAll 方法中,它将返回数据库中所有员工的列表。

配置实体框架服务

要拥有可用的实体框架 DBContext,我们需要更改应用程序的配置。我们需要添加一个连接字符串,以便我们的 DBContext 知道要转到哪个服务器以及要查询哪个数据库。

  • 我们将把连接字符串放在一个 JSON 配置文件中。

  • 我们还需要在 Startup 类的 ConfigureServices 方法中添加更多服务。

  • 实体框架,就像 ASP.NET 和 MVC 框架一样,实体框架依赖于依赖注入,为了注入工作,运行时需要了解实体框架使用的各种服务。

  • 有一个简单的配置 API 可以添加我们需要的所有默认服务。

让我们转到 AppSettings.json 文件并添加连接字符串,如以下程序所示。

{ 
   "message": "Hello, World! this message is from configuration file...", 
   "database": { 
      "connection": "Data Source=(localdb)\\mssqllocaldb;Initial Catalog=FirstAppDemo" 
   } 
}

现在让我们转到 Startup 类,我们需要在其中添加一些额外的服务以使实体框架正常工作。具体来说,我们需要做三件与实体框架相关的事情 –

  • 我们需要添加核心实体框架服务。

  • 我们还需要添加 SQL Server 相关的实体框架服务。

  • 我们需要告诉实体框架我们的 DBContext。

所有这些都可以通过可用作IServiceCollection上的扩展方法的方法来完成,如以下程序所示。

public void ConfigureServices(IServiceCollection services) { 
   services.AddMvc(); 
   services.AddEntityFramework() 
      .AddSqlServer() 
      .AddDbContext<FirstAppDemoDbContext>
   
   (option => option.UseSqlServer(Configuration["database:connection"])); 
} 
  • 第一种方法是AddEntityFramework这将添加核心实体框架服务,即默认服务。

  • 但是由于 Entity Framework 现在设计用于处理不同类型的数据库,包括非关系数据库,我们需要进行第二次调用以告诉 Entity Framework 添加其默认的 SQL Server 相关服务。

  • 然后我们还需要将我的DBContext告诉实体框架,以便它可以适当地构造该类的实例,我们可以通过第三个方法AddDbContext方法来做到这一点

  • 这个需要一个泛型类型参数,我们在其中指定 DBContext 派生类的类型FirstAppDemoDbContext

  • 在 AddDbContext 内部,我们需要描述 DBContext 的选项。

  • 这可以通过lambda 表达式来完成这是我们接收选项参数的操作,并且实体框架可以支持不同的数据库。我们需要做的就是告诉实体框架这个特定的 DBContext 将使用UseSqlServer

  • 此方法需要一个参数,即要使用connectionString

下面是Startup.cs文件的完整实现

using Microsoft.AspNet.Mvc; 

using FirstAppDemo.ViewModels; 
using FirstAppDemo.Services; 
using FirstAppDemo.Entities; 
using FirstAppDemo.Models; 

using System.Collections.Generic; 
using System.Linq;  

namespace FirstAppDemo.Controllers { 
   public class HomeController : Controller { 
      public ViewResult Index() { 
         var employee = new Employee { Id = 1, Name = "Mark Upston1" }; 
         using (var context = new 
         
         FirstAppDemoDbContext()) { 
            SQLEmployeeData sqlData = new SQLEmployeeData(context); 
            sqlData.Add(employee); 
         } 
         
         //var employee = new Employee { ID = 1, Name = "Mark Upston" }; 
         return View(employee); 
      } 
   }  
   public class SQLEmployeeData { 
      private FirstAppDemoDbContext _context { get; set; }  
      public SQLEmployeeData(FirstAppDemoDbContext context) { 
         _context = context; 
      }  
      public void Add(Employee emp) { 
         _context.Add(emp); 
         _context.SaveChanges(); 
      } 
      public Employee Get(int ID) { 
         return _context.Employees.FirstOrDefault(e => e.Id == ID); 
      } 
      public IEnumerable<Employee> GetAll() { 
         return _context.Employees.ToList<Employee>(); 
      } 
   } 
} 

现在我们需要设置数据库。设置数据库的一种方法是使用实​​体框架创建数据库,这是一个两步过程 –

第一步

这涉及以下内容 –

  • 将迁移代码添加到我们的项目中。

  • 迁移代码是C#代码。可以执行此操作以在数据库模式中创建数据库。

  • Entity Framework 可以为我们生成这个迁移代码。

  • 实体框架查看数据库和我们的模型,并找出使应用程序工作所需的架构更改。

  • 因此,当我们添加其他模型或对现有模型进行更改时,例如 Employee 类,我们可以继续向我们的项目添加迁移并保持我们的数据库架构同步。

第二步

这涉及以下内容 –

  • 在这里,我们需要显式应用这些迁移来更新数据库。

  • 这两项任务都可以通过使用控制台窗口中的一些简单命令来实现。

  • 我们已经制作了 project.json。

  • 这就是为什么我们在 project.json 中添加了一个命令,其中“ef”映射到 EntityFramework.Commands。

让我们打开 Visual Studio 的开发人员命令提示符来运行我们需要添加迁移和应用迁移的命令。最简单的方法是转到应用程序根目录。

开发人员命令提示符

如果您位于包含 project.json 文件的文件夹中,则您位于正确的文件夹中。在这里,我们需要执行一个名为 dnvm 的命令。这是 .NET 版本管理器,它将告诉系统我们想要使用什么运行时。

现在让我们使用以下命令。

dnvm list 

当您按 Enter 时,您将看到以下输出。

命令提示符中的输出

我们需要告诉dnvm我们要使用特定的运行时。这将使我们能够访问要执行的 dotnet 命令或 dnx 命令。

执行以下命令。

dnvm use1.0.0-rc1-update1 -p

按 Enter。

网络虚拟机

dnvm将设置我们的路径和环境变量以包含一个 bin 目录,该目录将使我们能够访问此 dnx 实用程序。让我们执行dnx ef命令。

DNX EF 命令

这是 .NET 执行环境,使用 dnx,我们可以调用我们在 project.json 文件中列出的命令。执行这些命令通常非常容易。当您键入 dnx ef 时,您将看到一个帮助屏幕。您不必记住所有选项。您可以从实体框架命令中看到可用的命令,其中包括三个。

首先,我们需要添加迁移来执行以下命令。

dnx ef migrations add v1

按 Enter。

DNX EF 迁移

实体框架将找到该上下文并查看其中的模型。它将知道之前没有迁移,因此它将生成第一次迁移。这里,v1 是数据库的版本 1。它将在解决方案资源管理器中创建一个新文件夹并生成代码。

实体框架

迁移本质上是一个 C# 代码,用于生成 SQL 命令以修改 SQL 数据库中的架构。

using System; 
using System.Collections.Generic; 

using Microsoft.Data.Entity.Migrations; 
using Microsoft.Data.Entity.Metadata;  

namespace FirstAppDemo.Migrations { 
   public partial class v1 : Migration { 
      protected override void Up(MigrationBuilder migrationBuilder) { 
         
         migrationBuilder.CreateTable(name: "Employee", 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_Employee", x => x.Id); 
         }); 
      }  
      protected override void Down(MigrationBuilder migrationBuilder) { 
         migrationBuilder.DropTable("Employee"); 
      } 
   } 
}

您可以看到它将创建一个名为Employees 的表。

  • 这个表应该有两列——一个 ID 和一个名称列。

  • 按照惯例,当实体框架看到您有一个名为 Id 的属性时,它将使该属性成为数据库中的主键,或者更确切地说,使该列成为主键。

  • 在这里,我们将使用 SQL Server。默认情况下,实体框架会将其设为 IdentityColumn,这意味着 SQL Server 将为我们生成 ID。

让我们通过键入“ dnx ef database update ”命令将这些 ID 应用于数据库

DNX EF 数据库更新

可以看到命令已经应用了迁移。

现在让我们转到 SQL Server 对象资源管理器,并刷新数据库,您现在可以看到我们有一个 FirstAppDemo 数据库。

SQL Server 对象探索

您还可以查看我们的 Employee 表,我们甚至可以查看该表的列,其中 ID 列是主键。

让我们右键单击 dbo.Employee 表并选择查看数据。

DBO 员工

在运行应用程序之前,让我们添加一些数据。当我们启动应用程序时,我们应该会看到一些来自数据库的数据。

让我们在这里添加几行数据。

几行数据

现在让我们更新 index.cshtml 文件。它以表格形式显示所有数据。

@model FirstAppDemo.Controllers.HomePageViewModel 
<html xmlns="http://www.w3.org/1999/xhtml"> 
   <head> 
       <title>Home</title> 
   </head> 

   <body> 
      <h1>Welcome!</h1> 
      
      <table> 
         @foreach (var employee in Model.Employees) { 
            <tr> 
               <td>   
                  @Html.ActionLink(employee.Id.ToString(), "Details", new 
                     { id = employee.Id }) 
               </td> 
               <td>@employee.Name</td> 
            </tr> 
         } 
      </table> 
   </body> 
</html>

运行应用程序后,它应该会产生以下输出。

最终输出

觉得文章有用?

点个广告表达一下你的爱意吧 !😁