微软官方案例
在本教程中,你将构建一个控制台应用程序,它使用 Entity Framework 对 Microsoft SQL Server 数据库执行基本数据访问。 通过对现有数据库进行反向工程,创建 Entity Framework 模型。
系统必备
创建博客数据库
本教程使用 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);
}
}
}
}
}