使用实体框架,您可以使用称为实体的公共语言运行时(CLR)对象来查询,插入,更新和删除数据.实体框架将模型中定义的实体和关系映射到数据库.它还为&提供了设施;
将从数据库返回的数据实体化为实体对象.
跟踪对对象所做的更改.
处理并发.
将对象更改传播回数据库.
将对象绑定到控件.
负责与数据交互作为对象的主类是DbContext.使用上下文的推荐方法是定义一个派生自DbContext的类,并公开表示上下文中指定实体集合的DbSet属性.
逻辑上,DBContext映射到具有DBContext理解的模式的特定数据库.在该DBContext类上,您可以创建类型为DbSet< T>的属性.泛型类型参数T将是一种类型的实体,例如Employee是FirstAppDemo应用程序中的实体.
让我们举一个简单的例子,其中我们将创建一个DbContext类.在这里,我们需要在Models文件夹中添加一个新类,并将其命名为 FirstAppDempDbContext .虽然这个类本身不是一个模型,但它确实将我们所有的模型组合在一起,以便我们可以将它们与数据库一起使用.
从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的开发人员命令提示符,以运行我们添加迁移所需的命令并应用迁移.最简单的方法是转到应用程序根目录.
如果您在具有project.json文件的文件夹中,那么您位于正确的文件夹中.在这里,我们需要执行一个名为dnvm的命令.这是.NET版本管理器,它将告诉系统我们想要使用什么运行时.
现在让我们使用以下命令.
dnvm list
当您按Enter键时,您将看到以下输出.
我们需要告诉我们想要的 dnvm 使用特定的运行时.这将使我们能够访问我们想要执行的dotnet命令或dnx命令.
执行以下命令.
dnvm use1.0.0-rc1-update1 -p
按Enter键.
dnvm 将设置我们的路径和环境变量以包含bin目录这将使我们能够访问此dnx实用程序.让我们执行 dnx ef 命令.
这是.NET执行环境,使用dnx,我们可以调用我们在project.json文件中列出的命令.执行这些命令通常非常容易.当您输入dnx ef时,您将看到一个帮助屏幕.您不必记住所有选项.您可以看到实体框架命令中的可用命令,其中有三个.
首先,我们需要添加迁移以执行以下命令.
dnx ef migrations add v1
按Enter键.
实体框架将找到该上下文并查看内部模型.它将知道以前没有迁移,因此它将生成第一次迁移.这里,v1是数据库的版本1.它将在Solution Explorer中创建一个新文件夹并生成代码.
迁移本质上是一个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写入数据库.
您可以看到该命令已应用迁移.
现在让我们转到SQL Server对象资源管理器,刷新数据库,你现在可以看到我们有一个FirstAppDemo数据库.
您还可以查看我们的员工表,我们甚至可以查看该表中主要键的列的列.
让我们正确 - 点击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>
运行应用程序后,它应该产生以下输出.