9.19 数据库生成模型

关于脚本

在阅读下面文档之前,必须把Furion 源码文件夹下的 tools/cli.ps1 文件拷贝到本地中。而且 Fur.Web.Entry 层需要安装 Microsoft.EntityFrameworkCore.Tools 包。

9.19.1 数据库开发方式#

Furion 提供两种主要方法来 保持实体模型和数据库架构同步

至于我们应该选用哪个方法,请确定你是希望以实体模型为准还是以数据库为准:

  • 如果希望 以实体模型为准,请使用正向工程(Code First)。 对实体模型进行更改时,此方法会以增量方式将相应架构更改应用到数据库,以使数据库保持与实体模型兼容。

  • 如果希望 以数据库架构为准,请使用反向工程(Database First)。 使用此方法,可通过将数据库架构反向工程到实体模型来生成相应的实体类型。

本章节是 反向工程(Database First) 的相关内容。

9.19.2 操作指南#

操作之前注意事项

目前 Furion Tools 生成工具默认不支持任何数据库生成,所以如需生成特定数据库的代码,只需要在 Furion.EntityFrameworkCore.Core 安装对应的数据库包即可:

各个数据库的包可查阅:多数据库操作-数据库提供器对应包

另外,只有 SqlServer 数据库支持可视化 GUI 操作,其他的只能命令行操作。

9.19.2.1 打开 程序包管理控制台#

注意:开始之前先把 Furion.Web.Entry 设为启动项目。

9.19.2.2 切换默认项目#

程序包管理控制台 默认项目设置为 Furion.Core,如果您是其他名字,则切换对应即可。

9.19.2.3 输入 cli.ps1 命令#

&"../tools/cli.ps1" -CoreProject "你的Core层" -EntryProject "你的启动层"
关于数据库命名

如果需要保持和数据库一模一样的命名,则使用 -UseDatabaseNames 参数指定,如:

&"../tools/cli.ps1" -UseDatabaseNames
等待输入

执行上面命令后,此时,Cli 有一个等待输入提示:

Furion Tools v1.0.0 请键入操作类型:[G] 界面操作,[任意字符] 命令行操作
Furion Tools v1.0.0 您的输入是:

输入大写 G 进入界面操作模式,其他任意字符进入命令行操作模式。

注意事项

目前只有 Sql Server 数据库才支持 GUI 界面操作模式,其他数据库请使用命令行模式。

9.19.3 界面操作模式#

9.19.3.1 启动界面操作#

当我们输入 G 时,将打开 GUI 界面操作模式,如:

这时,Furion Tools 会自动查找所有数据库配置连接字符串的 .json 文件:

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"Microsoft.EntityFrameworkCore": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DbConnectionString": "Server=localhost;Database=Furion;User=sa;Password=000000;MultipleActiveResultSets=True;",
"Sqlite3ConnectionString": "Data Source=./Furion.db"
}
}

9.19.3.2 加载数据库表#

选择连接字符串之后,点击 加载数据库表和视图 按钮加载。

9.19.3.3 选择表或视图生成#

加载表完成后,可以选择您要生成的表或视图,支持多选

点击底部按钮 立即生成

9.19.3.4 选择保存目录#

点击 立即生成 按钮后,会弹出实体保存选择目录资源管理器,默认实体只能保存在 Furion.Core 层:

点击确定后就可完成所有生成操作。

9.19.3.5 生成最终实体代码#

最终脚本如下:

PM> &"../tools/cli.ps1"
// -----------------------------------------------------------------------------
// ______ _______ _
// | ____| |__ __| | |
// | |__ _ _ _ __ | | ___ ___ | |___
// | __| | | | '__| | |/ _ \ / _ \| / __|
// | | | |_| | | | | (_) | (_) | \__ \
// |_| \__,_|_| |_|\___/ \___/|_|___/
//
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020 Furion, Baiqian Co.,Ltd.
//
// 框架名称:Furion
// 框架作者:百小僧
// 框架版本:1.0.0
// 源码地址:https://gitee.com/monksoul/Furion
// 开源协议:Apache-2.0(http://www.apache.org/licenses/LICENSE-2.0)
// -----------------------------------------------------------------------------
Furion Tools v1.0.0 启动中......
Furion Tools v1.0.0 启动成功!
Furion Tools v1.0.0 请键入操作类型:[G] 界面操作,[任意字符] 命令行操作
Furion Tools v1.0.0 您的输入是: G
Furion Tools v1.0.0 正在加载数据库表和视图......
Furion Tools v1.0.0 加载成功!
Furion Tools v1.0.0 正在编译解决方案代码......
Build started...
Build succeeded.
For foreign key FK_PersonDetail_Person_PersonId on table dbo.PersonDetail, unable to model the end of the foreign key on principal table dbo.Person. This is usually because the principal table was not included in the selection set.
Furion Tools v1.0.0 编译成功!
Furion Tools v1.0.0 开始生成实体文件......
Furion Tools v1.0.0 正在生成 City.cs 实体代码......
Furion Tools v1.0.0 成功生成 City.cs 实体代码
// -----------------------------------------------------------------------------
// 以下代码由 Furion Tools v1.0.0 生成
// -----------------------------------------------------------------------------
using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
#nullable disable
namespace Furion.Core
{
public partial class City : IEntity, IEntityTypeBuilder<City>
{
public City()
{
InverseParent = new HashSet<City>();
}
public int Id { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
public DateTime CreatedTime { get; set; }
public DateTime? UpdatedTime { get; set; }
public bool IsDeleted { get; set; }
public virtual City Parent { get; set; }
public virtual ICollection<City> InverseParent { get; set; }
public void Configure(EntityTypeBuilder<City> entityBuilder, DbContext dbContext, Type dbContextLocator)
{
entityBuilder.HasIndex(e => e.ParentId, "IX_City_ParentId");
entityBuilder.HasOne(d => d.Parent)
.WithMany(p => p.InverseParent)
.HasForeignKey(d => d.ParentId);
}
}
}
Furion Tools v1.0.0 正在生成 PersonDetail.cs 实体代码......
Furion Tools v1.0.0 成功生成 PersonDetail.cs 实体代码
// -----------------------------------------------------------------------------
// 以下代码由 Furion Tools v1.0.0 生成
// -----------------------------------------------------------------------------
using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
#nullable disable
namespace Furion.Core
{
public partial class PersonDetail : IEntity, IEntityTypeBuilder<PersonDetail>
{
public int Id { get; set; }
public string PhoneNumber { get; set; }
public string Qq { get; set; }
public int PersonId { get; set; }
public void Configure(EntityTypeBuilder<PersonDetail> entityBuilder, DbContext dbContext, Type dbContextLocator)
{
entityBuilder.HasIndex(e => e.PersonId, "IX_PersonDetail_PersonId")
.IsUnique();
entityBuilder.Property(e => e.Qq).HasColumnName("QQ");
}
}
}
Furion Tools v1.0.0 正在生成 Post.cs 实体代码......
Furion Tools v1.0.0 成功生成 Post.cs 实体代码
// -----------------------------------------------------------------------------
// 以下代码由 Furion Tools v1.0.0 生成
// -----------------------------------------------------------------------------
using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
#nullable disable
namespace Furion.Core
{
public partial class Post : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreatedTime { get; set; }
public DateTime? UpdatedTime { get; set; }
public bool IsDeleted { get; set; }
}
}
Furion Tools v1.0.0 正在生成 VPerson.cs 实体代码......
Furion Tools v1.0.0 成功生成 VPerson.cs 实体代码
// -----------------------------------------------------------------------------
// 以下代码由 Furion Tools v1.0.0 生成
// -----------------------------------------------------------------------------
using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
#nullable disable
namespace Furion.Core
{
public partial class VPerson : IEntity, IEntityTypeBuilder<VPerson>
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public void Configure(EntityTypeBuilder<VPerson> entityBuilder, DbContext dbContext, Type dbContextLocator)
{
entityBuilder.HasNoKey();
entityBuilder.ToView("V_Person");
entityBuilder.Property(e => e.Id).ValueGeneratedOnAdd();
entityBuilder.Property(e => e.Name).HasMaxLength(32);
}
}
}
Furion Tools v1.0.0 全部实体生成成功!
PM>

9.19.4 命令参数配置#

Furion Tools Cli 支持多个参数配置,使用方法只需要在命令后面添加即可,如:

&"../tools/cli.ps1" -Context 数据库上下文名 -ConnectionName 连接字符串Key

支持参数如下:

  • -Tables:配置要生成的数据库表,数组类型,如果为空,则生成数据库所有表和视图。如:-Tables Person,PersonDetails
  • -Context:配置数据库上下文,默认 FurDbContext,如果有多个数据库上下文,则此参数必须配置
  • -ConnectionName:配置数据库连接字符串,对于 appsetting.json 中的 Key
  • -OutputDir:生成实体代码输出目录,默认为:./Furion.Core/Entities/
  • -DbProvider:数据库提供器,默认是 Microsoft.EntityFrameworkCore.SqlServer,其他数据库请指定对应程序集
    • SqlServerMicrosoft.EntityFrameworkCore.SqlServer
    • SqliteMicrosoft.EntityFrameworkCore.Sqlite
    • CosmosMicrosoft.EntityFrameworkCore.Cosmos
    • InMemoryDatabaseMicrosoft.EntityFrameworkCore.InMemory
    • MySqlPomelo.EntityFrameworkCore.MySql
    • PostgreSQLNpgsql.EntityFrameworkCore.PostgreSQL
    • OracleCitms.EntityFrameworkCore.Oracle
    • DmMicrosoft.EntityFrameworkCore.Dm
  • -EntryProject:Web 启用项目层名,默认 Furion.Web.Entry
  • -CoreProject:实体项目层名,默认 Furion.Core
  • -DbContextLocators:多数据库上下文定位器,默认 MasterDbContextLocator,支持多个,如:MasterDbContextLocator,MySqlDbContextLocator
  • -Product:解决方案默认前缀,如 Furion
  • -UseDatabaseNames:是否保持生成和数据库、表一致的名称
  • -Namespace:指定实体命名空间

9.19.5 反馈与建议#

与我们交流

给 Furion 提 Issue