ASP.NET Core - DBContext

使用实体框架,您可以使用称为实体的公共语言运行时(CLR)对象来查询,插入,更新和删除数据.实体框架将模型中定义的实体和关系映射到数据库.它还为&提供了设施;

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

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

  • 处理并发.

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

  • 将对象绑定到控件.

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

DBContext

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

示例

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

FirstAppDemo Context

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

每个DbSet将映射到数据库中的表.如果您拥有employee的属性DbSet,并且该属性的名称是Employees,则Entity Framework将默认在数据库中查找Employees表.

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; } 
   } 
}


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

现在让我们直接插入此类然后控制器可以使用 FirstAppDemoDbContext 来查询数据库.我们将通过向HomeController类添加一个新类来简化所有这些,我们在其中实现Add employee和Get employee的方法,如下面的程序所示.

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类,我们需要为Entity Framework添加一些额外的服务才能正常工作.具体来说,我们需要做三件与实体框架相关的事情 :

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

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

  • 我们需要告诉Entity Framework我们的DBContext.

这一切都可以通过可用的方法来完成作为 IServiceCollection 的扩展方法,如以下程序所示.

public void ConfigureServices(IServiceCollection services) { 
   services.AddMvc(); 
   services.AddEntityFramework() 
      .AddSqlServer() 
      .AddDbContext<FirstAppDemoDbContext>
   
   (option => option.UseSqlServer(Configuration["database:connection"])); 
}


  • 第一种方法是 AddEntityFramework .这将添加核心实体框架服务,默认服务.

  • 但由于实体框架现在设计用于不同类型的数据库,包括非关系数据库,我们需要进行第二次调用,告诉实体框架添加其默认的SQL Server相关服务.

  • 然后我们还需要告诉关于我的 DBContext 类的实体框架,因此它可以适当地构造该类的实例,我们可以通过第三种方法 AddDbContext 方法来实现.

  • 这个参数采用泛型类型参数,我们指定DBContext派生类的类型, FirstAppDemoDbContext .

  • 在AddDbContext中,我们需要描述DBContext的选项.

  • 这可以通过 lambda表达式完成的;这是一个我们收到选项参数的动作,实体框架可以支持不同的数据库.我们需要做的就是告诉实体框架这个特定的DBContext要去 UseSqlServer .

  • 这个方法需要一个参数这是要使用的 connectionString .

以下是启动的完整实现. cs file.

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>(); 
      } 
   } 
}


现在我们需要设置数据库.设置数据库的一种方法是使用Entity Framework创建数据库,这是一个两步过程 :

第一步

这涉及以下 :

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

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

  • 实体框架可以为我们生成此迁移代码.

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

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

第二步

这涉及以下 :

  • 在这里,我们需要明确应用这些迁移来更新数据库.

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

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

  • 这就是为什么我们让project.json添加一个命令,其中"ef"映射到EntityFramework.Comma nds.

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

Developer Command Prompt

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

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

dnvm list


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

命令提示输出

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

执行以下命令.

dnvm use1.0.0-rc1-update1 -p


按Enter键.

DNVM

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

DNX EF Command

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

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

dnx ef migrations add v1


按Enter键.

DNX EF Migrations

实体框架将找到该上下文并查看内部模型.它将知道以前没有迁移,因此它将生成第一次迁移.这里,v1是数据库的版本1.它将在Solution Explorer中创建一个新文件夹并生成代码.

Entity Framework

迁移本质上是一个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和一个Name列.

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

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

让我们申请通过键入" dnx ef database update "命令将这些ID写入数据库.

DNX EF数据库更新

您可以看到该命令已应用迁移.

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

SQL Server Object Explore

您还可以查看我们的员工表,我们甚至可以查看该表中主要键的列的列.

让我们正确 - 点击dbo.Employee表并选择查看数据.

DBO Employee

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

我们在这里添加几行数据.

一对行数据

现在让我们更新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>


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

最终输出