持久层重构为独立 MiGu.DB 工程并优化集成
- 新增 MiGu.DB 项目,迁移所有领域实体与枚举,统一模型约定 - 实现 Entity/Repository/UoW/Provider/Exception 等接口与实现 - 支持数据修补机制,完善 Sqlite 初始迁移与数据库管理 - Server 侧移除 EF Core 相关,依赖 MiGu.DB,PlatformPersistence 适配 - 业务服务注入 UoW/Repository,状态字段统一用 enum 及辅助类 - 统一异常处理,Controller 映射 HTTP 状态码 - 配置项与文档补充数据库启动、SchemaMode、迁移说明 - 新增 GlobalUsings.Db.cs、WmsStatusAliases.cs 简化类型引用 - 新增 HttpActorContextMiddleware 支持操作者上下文一致性 - 新增 MiGuDbContextModelSnapshot 追踪数据库结构 - 优化代码结构,解耦领域与持久层,提升扩展性与安全性
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MiGu.DB.Abstractions.Runtime;
|
||||
using MiGu.DB.Domains.Wms;
|
||||
using MiGu.DB.Kernel.Context;
|
||||
|
||||
namespace MiGu.DB.Domains.Migrators;
|
||||
|
||||
// 启动期数据修补:Schema 初始化之后按 Order 执行,须幂等。
|
||||
// 优先 LINQ / ExecuteUpdateAsync;枚举 converter 无法匹配旧字符串时允许定点 raw UPDATE(Sqlite)。
|
||||
|
||||
/// <summary>将 simple_fields.other 回填到 car_type(替代原 PlatformPersistence raw UPDATE)。</summary>
|
||||
public sealed class SimpleFieldsCarTypeBackfillMigrator : IDataMigrator
|
||||
{
|
||||
public int Order => 10;
|
||||
public string Name => "SimpleFields.CarTypeBackfill";
|
||||
|
||||
public async Task MigrateAsync(DbContext db, CancellationToken ct = default)
|
||||
{
|
||||
if (db is not MiGuDbContext ctx) return;
|
||||
|
||||
await ctx.SimpleFields
|
||||
.Where(x => (x.CarType == null || x.CarType == "") && x.Other != "")
|
||||
.ExecuteUpdateAsync(s => s.SetProperty(x => x.CarType, x => x.Other), ct);
|
||||
|
||||
await ctx.SimpleFields
|
||||
.Where(x => x.Other != "" && x.Other == x.CarType)
|
||||
.ExecuteUpdateAsync(s => s.SetProperty(x => x.Other, ""), ct);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 把库内旧状态字符串刷成规范枚举名(Available/Idle→Empty,Occupied→FullContainer)。
|
||||
/// 仅 Sqlite 表名/列名;绕过枚举 HasConversion(ExecuteUpdate + 字符串比较会 InvalidCast)。
|
||||
/// </summary>
|
||||
public sealed class LegacyStatusNormalizationMigrator : IDataMigrator
|
||||
{
|
||||
public int Order => 15;
|
||||
public string Name => "Wms.LegacyStatusNormalization";
|
||||
|
||||
public async Task MigrateAsync(DbContext db, CancellationToken ct = default)
|
||||
{
|
||||
if (db is not MiGuDbContext) return;
|
||||
|
||||
await db.Database.ExecuteSqlRawAsync(
|
||||
"""
|
||||
UPDATE wms_storages
|
||||
SET Status = 'Empty'
|
||||
WHERE Status IN ('Available', 'Idle')
|
||||
""",
|
||||
ct);
|
||||
|
||||
await db.Database.ExecuteSqlRawAsync(
|
||||
"""
|
||||
UPDATE wms_storages
|
||||
SET Status = 'FullContainer'
|
||||
WHERE Status = 'Occupied'
|
||||
""",
|
||||
ct);
|
||||
|
||||
await db.Database.ExecuteSqlRawAsync(
|
||||
"""
|
||||
UPDATE wms_areas
|
||||
SET LayoutMode = 'Flat'
|
||||
WHERE LayoutMode IS NULL OR LayoutMode = ''
|
||||
""",
|
||||
ct);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// LocationType=Storage 时回填 StorageId,供库存 join;写路径 BindOrTransferLocation 也会维护该字段。
|
||||
/// </summary>
|
||||
public sealed class ContainerLocationStorageIdBackfillMigrator : IDataMigrator
|
||||
{
|
||||
public int Order => 20;
|
||||
public string Name => "Wms.ContainerLocation.StorageId";
|
||||
|
||||
public async Task MigrateAsync(DbContext db, CancellationToken ct = default)
|
||||
{
|
||||
if (db is not MiGuDbContext ctx) return;
|
||||
|
||||
var rows = await ctx.ContainerLocations
|
||||
.Where(x => x.LocationType == ContainerLocationType.Storage && x.StorageId == null)
|
||||
.ToListAsync(ct);
|
||||
foreach (var row in rows)
|
||||
{
|
||||
if (Guid.TryParse(row.LocationId, out var sid))
|
||||
row.StorageId = sid;
|
||||
}
|
||||
if (rows.Count > 0)
|
||||
await ctx.SaveChangesAsync(ct);
|
||||
}
|
||||
}
|
||||
|
||||
public static class DataMigratorRegistration
|
||||
{
|
||||
public static IServiceCollection AddMiGuDataMigrators(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IDataMigrator, SimpleFieldsCarTypeBackfillMigrator>();
|
||||
services.AddSingleton<IDataMigrator, LegacyStatusNormalizationMigrator>();
|
||||
services.AddSingleton<IDataMigrator, ContainerLocationStorageIdBackfillMigrator>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user