通过现有数据库在 .NET Framework 上开始使用 EF Core

微软官方案例

在本教程中,你将构建一个控制台应用程序,它使用 Entity Framework 对 Microsoft SQL Server 数据库执行基本数据访问。 通过对现有数据库进行反向工程,创建 Entity Framework 模型。

在 GitHub 上查看此文章的示例

系统必备

创建博客数据库

本教程使用 LocalDb 实例上的博客数据库作为现有数据库。 如果已在其他教程中创建了博客数据库,请跳过这些步骤。

  • 打开 Visual Studio
  • “工具”->“连接到数据库…”
  • 选择“Microsoft SQL Server”,然后单击“继续”
  • 输入“(localdb)\mssqllocaldb”作为服务器名称
  • 输入“master”作为数据库名称,然后单击“确定”
  • Master 数据库现在显示在“服务器资源管理器”的“数据连接”中
  • 右键单击“服务器资源管理器”中的数据库,然后选择“新建查询”
  • 将下列脚本复制到查询编辑器中
  • 右键单击查询编辑器,然后选择“执行”

SQL复制

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

创建新项目

  • 打开 Visual Studio 2017
  • “文件”>“新建”>“项目…”
  • 从左侧菜单中选择“已安装”>“Visual C#”->“Windows Desktop”
  • 选择“控制台应用(.NET Framework)”项目模板
  • 确保项目面向 .NET Framework 4.6.1 或更高版本
  • 将项目命名为 ConsoleApp.ExistingDb,并单击“确定”

安装 Entity Framework

要使用 EF Core,请为要作为目标对象的数据库提供程序安装程序包。 本教程使用 SQL Server。 有关可用提供程序的列表,请参阅数据库提供程序

  • “工具”>“NuGet 包管理器”>“包管理器控制台”
  • 运行 Install-Package Microsoft.EntityFrameworkCore.SqlServer

下一步,要使用一些 Entity Framework Tools 对该数据库进行反向工程。 因此,请同时安装该工具包。

  • 运行 Install-Package Microsoft.EntityFrameworkCore.Tools

对模型实施反向工程

现在是时候基于现有数据库创建 EF 模型了。

  • “工具”–>“NuGet 包管理器”–>“包管理器控制台”
  • 运行以下命令以从现有数据库创建模型PowerShell复制Scaffold-DbContext "Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer

 提示

可以通过将 -Tables 参数添加到上述命令来指定要为其生成实体的表。 例如 -Tables Blog,Post

反向工程过程基于现有数据库的架构创建实体类(Blog 和 Post)和派生上下文(BloggingContext)。

实体类是简单的 C# 对象,代表要查询和保存的数据。 以下是 Blog 和 Post 实体类:C#复制

using System;
using System.Collections.Generic;

namespace ConsoleApp.ExistingDb
{
    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; }
    }
}

C#复制

using System;
using System.Collections.Generic;

namespace ConsoleApp.ExistingDb
{
    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)。

上下文表示与数据库的会话。 其中有可用于查询和保存实体类实例的方法。C#复制

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace ConsoleApp.ExistingDb
{
    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);
            });
        }
    }
}

使用模型

现在可以使用模型执行数据访问。

  • 打开 Program.cs
  • 将此文件的内容替换为以下代码C#复制
  • “调试”>“开始执行(不调试)”可以看到,把一个博客保存到数据库后,所有博客的详细信息都将显示在控制台中。
using System;

namespace ConsoleApp.ExistingDb
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var db = new BloggingContext())
            {
                db.Blog.Add(new Blog { Url = "http://blogs.msdn.com/adonet" });
                var count = db.SaveChanges();
                Console.WriteLine("{0} records saved to database", count);

                Console.WriteLine();
                Console.WriteLine("All blogs in database:");
                foreach (var blog in db.Blog)
                {
                    Console.WriteLine(" - {0}", blog.Url);
                }
            }
        }
    }
}
图像

Leave a Comment