前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Entity Framework Core 总结

Entity Framework Core 总结

作者头像
yiyun
发布2022-04-01 16:23:44
1.1K0
发布2022-04-01 16:23:44
举报
文章被收录于专栏:yiyun 的专栏yiyun 的专栏

.NET Core CLI

此种方法对于 ASP.NET Core 也可以使用,其实当执行命令 dotnet ef migrations 时,会启动所在程序集(Program.cs),和正常启动ASP.NET Core 一样,所以会依赖注入 MyDbContext等

代码语言:javascript
复制
# 全局安装 EF Core 工具
dotnet tool install --global dotnet-ef

# 安装 设计包,这是对项目运行命令所必需的
dotnet add package Microsoft.EntityFrameworkCore.Design

# migrations 命令为迁移搭建基架,以便为模型创建一组初始表
dotnet ef migrations add InitialCreate

# database update 命令创建数据库并向其应用新的迁移
dotnet ef database update

dotnet ef migrations add InitialCreate 创建描述表结构的代码文件

EF Core 有两个工具集

  1. .NET Core 命令行接口 (CLI) 工具可用于 Windows、Linux 或 macOS。 这些命令以 dotnet ef 开头。
  2. 包管理器控制台 (PMC) 工具在 Windows 上的 Visual Studio 中运行。 这些命令以动词开头,例如 Add-MigrationUpdate-Database

为了跨平台 应用,同时也便于编写Shell脚本,建议使用 .NET Core CLI ,不依赖于 Visual Studio

在 ASP.NET Core 中初始化数据库

这是另一种创建表结构,初始化表数据的方式,而不是用CLI,这是在启动ASP.NET Core时执行。 用这种方法,无需 Migrations代码文件,也无需 b => b.MigrationsAssembly("WebApi") ,将在程序启动时,创建表结构(context.Database.EnsureCreated();),当然创建完表结构后,可以设定数据库种子(初始化表数据)

参考:ASP.NET Core 中的 Razor Pages 和 Entity Framework Core - 第 1 个教程(共 8 个) | Microsoft Docs

创建数据库

Program.cs

代码语言:javascript
复制
using ContosoUniversity.Data;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;

namespace ContosoUniversity
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = CreateHostBuilder(args).Build();

            CreateDbIfNotExists(host);

            host.Run();
        }

        private static void CreateDbIfNotExists(IHost host)
        {
            using (var scope = host.Services.CreateScope())
            {
                var services = scope.ServiceProvider;
                try
                {
                    var context = services.GetRequiredService<SchoolContext>();
                    context.Database.EnsureCreated();
                    // DbInitializer.Initialize(context);
                }
                catch (Exception ex)
                {
                    var logger = services.GetRequiredService<ILogger<Program>>();
                    logger.LogError(ex, "An error occurred creating the DB.");
                }
            }
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

如果有上下文的数据库,则 EnsureCreated 方法不执行任何操作。 如果没有数据库,则它将创建数据库和架构。 EnsureCreated 启用以下工作流来处理数据模型更改:

  • 删除数据库。 任何现有数据丢失。
  • 更改数据模型。 例如,添加 EmailAddress 字段。
  • 运行应用。
  • EnsureCreated 创建具有新架构的数据库。

在无需保存数据的情况下,当架构快速发展时,此工作流在早期开发过程中表现良好。 如果需要保存已输入数据库的数据,情况就有所不同了。 如果是这种情况,请使用迁移。

设定数据库种子

Data/DbInitializer.cs

代码语言:javascript
复制
using ContosoUniversity.Data;
using ContosoUniversity.Models;
using System;
using System.Linq;

namespace ContosoUniversity.Data
{
    public static class DbInitializer
    {
        public static void Initialize(SchoolContext context)
        {
            context.Database.EnsureCreated();

            // Look for any students.
            if (context.Students.Any())
            {
                return;   // DB has been seeded
            }

            var students = new Student[]
            {
                new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2019-09-01")},
                new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2017-09-01")},
                new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2018-09-01")},
                new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2017-09-01")},
                new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2017-09-01")},
                new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2016-09-01")},
                new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2018-09-01")},
                new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2019-09-01")}
            };

            context.Students.AddRange(students);
            context.SaveChanges();
    }
}

Q&A

Q: EF Core 创建数据库 报错: 'Method 'Create' in type 'MySql.Data.EntityFrameworkCore.Query.Internal.My......

A: 降低设计器版本到 3.x

代码语言:javascript
复制
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.7">
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    <PrivateAssets>all</PrivateAssets>
</PackageReference>

Q:

代码语言:javascript
复制
dotnet ef migrations add InitialCreate
代码语言:javascript
复制
Your target project 'WebApi' doesn't match your migrations assembly 'Repositories'. Either change your target project or change your migrations assembly.
Change your migrations assembly by using DbContextOptionsBuilder. E.g. options.UseSqlServer(connection, b => b.MigrationsAssembly("WebApi")). By default, the migrations assembly is the assembly containing the DbContext.
Change your target project to the migrations project by using the Package Manager Console's Default project drop-down list, or by executing "dotnet ef" from the directory containing the migrations project.

A: WebApi.Startup.ConfigureServices

代码语言:javascript
复制
services.AddDbContext<RemDbContext>(options =>
	options.UseMySQL(connStr, b => b.MigrationsAssembly("WebApi")));

即, dotnet ef 的 默认 Migration 位于 DbContext 所在 Assembly,需要手动设置 MigrationsAssembly

WebApi 即 AssemblyName 可用下方代码获取

代码语言:javascript
复制
string migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

Q: 当多个 DbContext.Database.EnsureCreated() 时,只有第一个有效?

A: 是的,因为 EnsureCreated() 保证数据库被创建(存在),当第一个执行后,就会有数据库、表,

所以,当后面的 EnsureCreated() 执行时,由于已经存在数据库,所以不做任何操作

这个时候,只有对后面的调用 Migrate(),例如下方:

代码语言:javascript
复制
this._applicationDbContext.Database.EnsureCreated();
this._configurationDbContext.Database.Migrate();
this._persistedGrantDbContext.Database.Migrate();

当然,也可以全部采用 Migrate():

代码语言:javascript
复制
this._applicationDbContext.Database.Migrate();
this._configurationDbContext.Database.Migrate();
this._persistedGrantDbContext.Database.Migrate();

注意:Migrate() 必须先生成 Migrations 代码文件,可使用 .NET CLI 生成:

代码语言:javascript
复制
dotnet ef migrations add InitialAspNetCoreIdentityDbMigration -c ApplicationDbContext -o Migrations/AspNetCoreIdentityDb

dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Migrations/IdentityServer/PersistedGrantDb

dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Migrations/IdentityServer/ConfigurationDb

参考

感谢帮助!

本文作者: yiyun

本文链接: https://moeci.com/posts/分类-dotnet/dotnet-efcore/

版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-01-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • .NET Core CLI
  • 在 ASP.NET Core 中初始化数据库
    • 创建数据库
      • 设定数据库种子
      • Q&A
      • 参考
      相关产品与服务
      数据库
      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
      http://www.vxiaotou.com