通过现有数据库在 ASP.NET Core 上开始使用 EF CoreGetting Started with EF Core on ASP.NET Core with an Existing Database

在本教程中,你将使用 Entity Framework Core 构建执行基本数据访问的 ASP.NET Core MVC 应用程序。In this tutorial, you build an ASP.NET Core MVC application that performs basic data access using Entity Framework Core. 要对现有数据库进行反向工程,以创建 Entity Framework 模型。You reverse engineer an existing database to create an Entity Framework model.

在 GitHub 上查看此文章的示例View this article's sample on GitHub.

系统必备Prerequisites

安装以下软件:Install the following software:

创建博客数据库Create Blogging database

本教程使用 LocalDb 实例上的博客数据库作为现有数据库。This tutorial uses a Blogging database on your LocalDb instance as the existing database. 如果已在其他教程中创建了博客数据库,请跳过这些步骤。If you have already created the Blogging database as part of another tutorial, skip these steps.

  • 打开 Visual StudioOpen Visual Studio
  • “工具”->“连接到数据库...”Tools -> Connect to Database...
  • 选择“Microsoft SQL Server”,然后单击“继续”Select Microsoft SQL Server and click Continue
  • 输入“(localdb)\mssqllocaldb”作为服务器名称Enter (localdb)\mssqllocaldb as the Server Name
  • 输入“master”作为数据库名称,然后单击“确定”Enter master as the Database Name and click OK
  • Master 数据库现在显示在“服务器资源管理器”的“数据连接”中The master database is now displayed under Data Connections in Server Explorer
  • 右键单击“服务器资源管理器”中的数据库,然后选择“新建查询”Right-click on the database in Server Explorer and select New Query
  • 将下列脚本复制到查询编辑器中Copy the script listed below into the query editor
  • 右键单击查询编辑器,然后选择“执行”Right-click on the query editor and select Execute
CREATE DATABASE [Blogging];
GO

USE [Blogging];
GO

CREATE TABLE [Blog] (
    [BlogId] int NOT NULL IDENTITY,
    [Url] nvarchar(max) NOT NULL,
    CONSTRAINT [PK_Blog] PRIMARY KEY ([BlogId])
);
GO

CREATE TABLE [Post] (
    [PostId] int NOT NULL IDENTITY,
    [BlogId] int NOT NULL,
    [Content] nvarchar(max),
    [Title] nvarchar(max),
    CONSTRAINT [PK_Post] PRIMARY KEY ([PostId]),
    CONSTRAINT [FK_Post_Blog_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blog] ([BlogId]) ON DELETE CASCADE
);
GO

INSERT INTO [Blog] (Url) VALUES
('http://blogs.msdn.com/dotnet'),
('http://blogs.msdn.com/webdev'),
('http://blogs.msdn.com/visualstudio')
GO

创建新项目Create a new project

  • 打开 Visual Studio 2017Open Visual Studio 2017
  • “文件”>“新建”>“项目...”File > New > Project...
  • 从左菜单中选择“已安装”>“Visual C#”>“Web”。From the left menu select Installed > Visual C# > Web
  • 选择“ASP.NET Core Web 应用程序”项目模板Select the ASP.NET Core Web Application project template
  • 输入 EFGetStarted.AspNetCore.ExistingDb 作为名称(它必须完全匹配稍后在代码中使用的命名空间),再单击“确定”Enter EFGetStarted.AspNetCore.ExistingDb as the name (it has to match exactly the namespace later used in the code) and click OK
  • 等待“新建 ASP.NET Core Web 应用程序”对话框显示出来Wait for the New ASP.NET Core Web Application dialog to appear
  • 确保目标框架下拉列表设置为 .NET Core,版本下拉列表设置为 ASP.NET Core 2.1Make sure that the target framework dropdown is set to .NET Core, and the version dropdown is set to ASP.NET Core 2.1
  • 选择“Web 应用程序(模型视图控制器)”模板Select the Web Application (Model-View-Controller) template
  • 确保将“身份验证”设置为“无身份验证”Ensure that Authentication is set to No Authentication
  • 单击“确定” Click OK

安装 Entity Framework CoreInstall Entity Framework Core

要安装 EF Core,请为要作为目标对象的 EF Core 数据库提供程序安装程序包。To install EF Core, you install the package for the EF Core database provider(s) you want to target. 有关可用提供程序的列表,请参阅数据库提供程序For a list of available providers see Database Providers.

对于本教程,无需安装提供程序包,因为本教程使用 SQL Server。For this tutorial, you don't have to install a provider package because the tutorial uses SQL Server. SQL Server 提供程序包包含在 Microsoft.AspnetCore.App 元包中。The SQL Server provider package is included in the Microsoft.AspnetCore.App metapackage.

对模型实施反向工程Reverse engineer your model

现在是时候基于现有数据库创建 EF 模型了。Now it's time to create the EF model based on your existing database.

  • “工具”–>“NuGet 包管理器”–>“包管理器控制台”Tools –> NuGet Package Manager –> Package Manager Console
  • 运行以下命令以从现有数据库创建模型:Run the following command to create a model from the existing database:
Scaffold-DbContext "Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

如果收到错误,指出 The term 'Scaffold-DbContext' is not recognized as the name of a cmdlet,请关闭并重新打开 Visual Studio。If you receive an error stating The term 'Scaffold-DbContext' is not recognized as the name of a cmdlet, then close and reopen Visual Studio.

提示

可以通过将 -Tables 参数添加到上述命令来指定要为哪些表生成实体。You can specify which tables you want to generate entities for by adding the -Tables argument to the command above. 例如 -Tables Blog,PostFor example, -Tables Blog,Post.

反向工程过程基于现有数据库的架构创建实体类 (Blog.cs & Post.cs) 和派生上下文 (BloggingContext.cs)。The reverse engineer process created entity classes (Blog.cs & Post.cs) and a derived context (BloggingContext.cs) based on the schema of the existing database.

实体类是简单的 C# 对象,代表要查询和保存的数据。The entity classes are simple C# objects that represent the data you will be querying and saving. 以下是 BlogPost 实体类:Here are the Blog and Post entity classes:

using System;
using System.Collections.Generic;

namespace EFGetStarted.AspNetCore.ExistingDb.Models
{
    public partial class Blog
    {
        public Blog()
        {
            Post = new HashSet<Post>();
        }

        public int BlogId { get; set; }
        public string Url { get; set; }

        public ICollection<Post> Post { get; set; }
    }
}
using System;
using System.Collections.Generic;

namespace EFGetStarted.AspNetCore.ExistingDb.Models
{
    public partial class Post
    {
        public int PostId { get; set; }
        public int BlogId { get; set; }
        public string Content { get; set; }
        public string Title { get; set; }

        public Blog Blog { get; set; }
    }
}

提示

若要启用延迟加载,可以创建导航属性 virtual(Blog.Post 和 Post.Blog)。To enable lazy loading, you can make navigation properties virtual (Blog.Post and Post.Blog).

上下文表示与数据库的会话,并允许查询和保存实体类的实例。The context represents a session with the database and allows you to query and save instances of the entity classes.

public partial class BloggingContext : DbContext
{
   public BloggingContext()
   {
   }

   public BloggingContext(DbContextOptions<BloggingContext> options)
       : base(options)
   {
   }

   public virtual DbSet<Blog> Blog { get; set; }
   public virtual DbSet<Post> Post { get; set; }

   protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
   {
       if (!optionsBuilder.IsConfigured)
       {
           #warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
           optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;");
       }
   }

   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
       modelBuilder.Entity<Blog>(entity =>
       {
           entity.Property(e => e.Url).IsRequired();
       });

       modelBuilder.Entity<Post>(entity =>
       {
           entity.HasOne(d => d.Blog)
               .WithMany(p => p.Post)
               .HasForeignKey(d => d.BlogId);
       });
   }
}

通过依赖关系注入注册上下文Register your context with dependency injection

依赖关系注入的概念是 ASP.NET Core 的核心。The concept of dependency injection is central to ASP.NET Core. 服务(例如 BloggingContext)在应用程序启动期间通过依赖关系注入进行注册。Services (such as BloggingContext) are registered with dependency injection during application startup. 然后,通过构造函数参数或属性为需要这些服务的组件(如 MVC 控制器)提供相应服务。Components that require these services (such as your MVC controllers) are then provided these services via constructor parameters or properties. 有关依赖关系注入的详细信息,请参阅 ASP.NET 网站上的文章依赖关系注入For more information on dependency injection see the Dependency Injection article on the ASP.NET site.

在 Startup.cs 中注册并配置上下文Register and configure your context in Startup.cs

若要使 BloggingContext 对 MVC 控制器可用,请将其注册为服务。To make BloggingContext available to MVC controllers, register it as a service.

  • 打开 Startup.csOpen Startup.cs
  • 在文件开头添加以下 using 语句Add the following using statements at the start of the file
using EFGetStarted.AspNetCore.ExistingDb.Models;
using Microsoft.EntityFrameworkCore;

现在,可以使用 AddDbContext(...) 方法将其注册为服务。Now you can use the AddDbContext(...) method to register it as a service.

  • 找到 ConfigureServices(...) 方法Locate the ConfigureServices(...) method
  • 添加以下突出显示的代码以将上下文注册为服务Add the following highlighted code to register the context as a service
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });


    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    var connection = @"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;ConnectRetryCount=0";
    services.AddDbContext<BloggingContext>(options => options.UseSqlServer(connection));
}

提示

在实际的应用程序中,通常会将连接字符串置于配置文件或环境变量中。In a real application you would typically put the connection string in a configuration file or environment variable. 为简单起见,本教程要你在代码中定义它。For the sake of simplicity, this tutorial has you define it in code. 有关详细信息,请参阅连接字符串For more information, see Connection Strings.

创建控制器和视图Create a controller and views

  • 在“解决方案资源管理器”中,右键单击“控制器”文件夹,然后选择“添加”->“控制器...”Right-click on the Controllers folder in Solution Explorer and select Add -> Controller...
  • 选择“视图使用 Entity Framework 的 MVC 控制器”,然后单击“确定”Select MVC Controller with views, using Entity Framework and click Ok
  • 将“模型类”设置为“Blog”,将“数据上下文类”设置为“BloggingContext”Set Model class to Blog and Data context class to BloggingContext
  • 单击“添加”Click Add

运行此应用程序Run the application

现在可以运行应用程序来查看其实际运行情况。You can now run the application to see it in action.

  • “调试”->“开始执行(不调试)”Debug -> Start Without Debugging

  • 应用程序将生成并在 Web 浏览器中打开The application builds and opens in a web browser

  • 导航到 /BlogsNavigate to /Blogs

  • 单击“新建”Click Create New

  • 输入新博客的 Url,然后单击“创建”Enter a Url for the new blog and click Create

    创建页面

    索引页

后续步骤Next steps

有关如何构建上下文和实体类的详细信息,请参阅以下文章:For more information about how to scaffold a context and entity classes, see the following articles: