feat: 将数据库模型和迁移集中到 EFCore 项目
- 将 AppDataContext、实体模型、Migrations 从 Avalonia-Services 移动到 Avalonia-EFCore - 更新 API、PC、Services 中的数据库上下文和实体引用命名空间 - 在实体上显式绑定表名、字段名和数据库注释 - 更新 InitialCreate、Designer、Snapshot,使用新的表名、字段名和注释 - 新增 AppDataContextFactory,支持 dotnet ef 设计时创建 DbContext - 新增本地 dotnet-ef 工具清单 - 新增一键生成迁移脚本 add-migration.ps1 / .cmd / .bat - 启动时自动检测并执行未应用迁移 - 从 appsettings.json 读取数据库配置
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using Avalonia_EFCore.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Avalonia_EFCore.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDataContext))]
|
||||
[Migration("20260514000100_InitialCreate")]
|
||||
partial class InitialCreate
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "10.0.0");
|
||||
|
||||
modelBuilder.Entity("Avalonia_EFCore.Models.UserEntity", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.HasComment("用户主键")
|
||||
.HasColumnName("id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasComment("创建时间")
|
||||
.HasColumnName("created-at");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasComment("用户邮箱")
|
||||
.HasColumnName("email")
|
||||
.HasMaxLength(200);
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasComment("用户名称")
|
||||
.HasColumnName("name")
|
||||
.HasMaxLength(100);
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasComment("更新时间")
|
||||
.HasColumnName("updated-at");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk-user");
|
||||
|
||||
b.ToTable("user", t =>
|
||||
{
|
||||
t.HasComment("用户实体,演示数据库 CRUD 操作");
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Avalonia_EFCore.Models.WeatherForecastEntity", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.HasComment("天气预报主键")
|
||||
.HasColumnName("id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasComment("创建时间")
|
||||
.HasColumnName("created-at");
|
||||
|
||||
b.Property<DateOnly>("Date")
|
||||
.HasComment("预报日期")
|
||||
.HasColumnName("date");
|
||||
|
||||
b.Property<string>("Summary")
|
||||
.HasComment("天气摘要")
|
||||
.HasColumnName("summary")
|
||||
.HasMaxLength(200);
|
||||
|
||||
b.Property<int>("TemperatureC")
|
||||
.HasComment("摄氏温度")
|
||||
.HasColumnName("temperature-c");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasComment("更新时间")
|
||||
.HasColumnName("updated-at");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk-weather-forecast");
|
||||
|
||||
b.ToTable("weather-forecast", t =>
|
||||
{
|
||||
t.HasComment("天气预报数据实体");
|
||||
});
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Avalonia_EFCore.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始数据库基线。后续软件版本只追加新的 Migration,不修改已发布 Migration。
|
||||
/// </summary>
|
||||
public partial class InitialCreate : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "user",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(name: "id", nullable: false, comment: "用户主键")
|
||||
.Annotation("SqlServer:Identity", "1, 1")
|
||||
.Annotation("Sqlite:Autoincrement", true)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Name = table.Column<string>(name: "name", maxLength: 100, nullable: true, comment: "用户名称"),
|
||||
Email = table.Column<string>(name: "email", maxLength: 200, nullable: true, comment: "用户邮箱"),
|
||||
CreatedAt = table.Column<DateTime>(name: "created-at", nullable: false, comment: "创建时间"),
|
||||
UpdatedAt = table.Column<DateTime>(name: "updated-at", nullable: false, comment: "更新时间")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk-user", x => x.Id);
|
||||
},
|
||||
comment: "用户实体,演示数据库 CRUD 操作");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "weather-forecast",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(name: "id", nullable: false, comment: "天气预报主键")
|
||||
.Annotation("SqlServer:Identity", "1, 1")
|
||||
.Annotation("Sqlite:Autoincrement", true)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Date = table.Column<DateOnly>(name: "date", nullable: false, comment: "预报日期"),
|
||||
TemperatureC = table.Column<int>(name: "temperature-c", nullable: false, comment: "摄氏温度"),
|
||||
Summary = table.Column<string>(name: "summary", maxLength: 200, nullable: true, comment: "天气摘要"),
|
||||
CreatedAt = table.Column<DateTime>(name: "created-at", nullable: false, comment: "创建时间"),
|
||||
UpdatedAt = table.Column<DateTime>(name: "updated-at", nullable: false, comment: "更新时间")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk-weather-forecast", x => x.Id);
|
||||
},
|
||||
comment: "天气预报数据实体");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "weather-forecast");
|
||||
migrationBuilder.DropTable(name: "user");
|
||||
}
|
||||
}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Avalonia_EFCore.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Avalonia_EFCore.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDataContext))]
|
||||
[Migration("20260515072045_AutoMigration_20260515152037")]
|
||||
partial class AutoMigration_20260515152037
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "10.0.0");
|
||||
|
||||
modelBuilder.Entity("Avalonia_EFCore.Models.UserEntity", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("id")
|
||||
.HasComment("用户主键");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("created-at")
|
||||
.HasComment("创建时间");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("email")
|
||||
.HasComment("用户邮箱");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("name")
|
||||
.HasComment("用户名称");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("phone-number")
|
||||
.HasComment("电话号码");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("updated-at")
|
||||
.HasComment("更新时间");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk-user");
|
||||
|
||||
b.ToTable("user", t =>
|
||||
{
|
||||
t.HasComment("用户实体,演示数据库 CRUD 操作");
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Avalonia_EFCore.Models.WeatherForecastEntity", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("id")
|
||||
.HasComment("天气预报主键");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("created-at")
|
||||
.HasComment("创建时间");
|
||||
|
||||
b.Property<DateOnly>("Date")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("date")
|
||||
.HasComment("预报日期");
|
||||
|
||||
b.Property<string>("Summary")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("summary")
|
||||
.HasComment("天气摘要");
|
||||
|
||||
b.Property<int>("TemperatureC")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("temperature-c")
|
||||
.HasComment("摄氏温度");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("updated-at")
|
||||
.HasComment("更新时间");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk-weather-forecast");
|
||||
|
||||
b.ToTable("weather-forecast", t =>
|
||||
{
|
||||
t.HasComment("天气预报数据实体");
|
||||
});
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Avalonia_EFCore.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AutoMigration_20260515152037 : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "phone-number",
|
||||
table: "user",
|
||||
type: "TEXT",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
comment: "电话号码");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "phone-number",
|
||||
table: "user");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Avalonia_EFCore.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Avalonia_EFCore.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDataContext))]
|
||||
partial class AppDataContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "10.0.0");
|
||||
|
||||
modelBuilder.Entity("Avalonia_EFCore.Models.UserEntity", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("id")
|
||||
.HasComment("用户主键");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("created-at")
|
||||
.HasComment("创建时间");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("email")
|
||||
.HasComment("用户邮箱");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("name")
|
||||
.HasComment("用户名称");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("phone-number")
|
||||
.HasComment("电话号码");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("updated-at")
|
||||
.HasComment("更新时间");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk-user");
|
||||
|
||||
b.ToTable("user", t =>
|
||||
{
|
||||
t.HasComment("用户实体,演示数据库 CRUD 操作");
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Avalonia_EFCore.Models.WeatherForecastEntity", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("id")
|
||||
.HasComment("天气预报主键");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("created-at")
|
||||
.HasComment("创建时间");
|
||||
|
||||
b.Property<DateOnly>("Date")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("date")
|
||||
.HasComment("预报日期");
|
||||
|
||||
b.Property<string>("Summary")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("summary")
|
||||
.HasComment("天气摘要");
|
||||
|
||||
b.Property<int>("TemperatureC")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("temperature-c")
|
||||
.HasComment("摄氏温度");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("updated-at")
|
||||
.HasComment("更新时间");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk-weather-forecast");
|
||||
|
||||
b.ToTable("weather-forecast", t =>
|
||||
{
|
||||
t.HasComment("天气预报数据实体");
|
||||
});
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user