持久层重构为独立 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,45 @@
|
||||
namespace MiGu.DB.Abstractions.Entities;
|
||||
|
||||
public interface IEntity<TKey>
|
||||
{
|
||||
TKey Id { get; set; }
|
||||
}
|
||||
|
||||
public interface IAuditable
|
||||
{
|
||||
DateTimeOffset CreatedAt { get; set; }
|
||||
DateTimeOffset UpdatedAt { get; set; }
|
||||
string CreatedBy { get; set; }
|
||||
string UpdatedBy { get; set; }
|
||||
}
|
||||
|
||||
public interface ISoftDeletable
|
||||
{
|
||||
bool IsDeleted { get; set; }
|
||||
DateTimeOffset? DeletedAt { get; set; }
|
||||
string DeletedBy { get; set; }
|
||||
}
|
||||
|
||||
public interface IVersioned
|
||||
{
|
||||
long Version { get; set; }
|
||||
}
|
||||
|
||||
public interface ILockable
|
||||
{
|
||||
bool IsLock { get; set; }
|
||||
}
|
||||
|
||||
public interface IRemarkable
|
||||
{
|
||||
string Remark { get; set; }
|
||||
}
|
||||
|
||||
public interface IExtendable
|
||||
{
|
||||
string Extend { get; set; }
|
||||
}
|
||||
|
||||
public interface IHistoryEntry
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
namespace MiGu.DB.Abstractions.Exceptions;
|
||||
|
||||
public sealed class ConcurrencyConflictException : Exception
|
||||
{
|
||||
public string EntityType { get; }
|
||||
public object? EntityId { get; }
|
||||
public long? ExpectedVersion { get; }
|
||||
|
||||
public ConcurrencyConflictException(string entityType, object? entityId, long? expectedVersion = null)
|
||||
: base("数据已被其他用户修改,请刷新后重试")
|
||||
{
|
||||
EntityType = entityType;
|
||||
EntityId = entityId;
|
||||
ExpectedVersion = expectedVersion;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class EntityLockedException : Exception
|
||||
{
|
||||
public string EntityType { get; }
|
||||
public object? EntityId { get; }
|
||||
|
||||
public EntityLockedException(string entityType, object? entityId)
|
||||
: base("数据已锁定,不能修改")
|
||||
{
|
||||
EntityType = entityType;
|
||||
EntityId = entityId;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class EntityNotFoundException : Exception
|
||||
{
|
||||
public string EntityType { get; }
|
||||
public object? EntityId { get; }
|
||||
|
||||
public EntityNotFoundException(string entityType, object? entityId)
|
||||
: base("数据不存在")
|
||||
{
|
||||
EntityType = entityType;
|
||||
EntityId = entityId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace MiGu.DB.Abstractions.Modules;
|
||||
|
||||
public interface IEntityModule
|
||||
{
|
||||
void ConfigureModel(ModelBuilder modelBuilder);
|
||||
void RegisterServices(IServiceCollection services);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.Linq.Expressions;
|
||||
using MiGu.DB.Abstractions.Entities;
|
||||
|
||||
namespace MiGu.DB.Abstractions.Persistence;
|
||||
|
||||
public interface IRepository<TEntity, TKey> where TEntity : class, IEntity<TKey>
|
||||
{
|
||||
IQueryable<TEntity> Query(bool asNoTracking = true);
|
||||
Task<TEntity?> FindAsync(TKey id, CancellationToken ct = default);
|
||||
Task AddAsync(TEntity entity, CancellationToken ct = default);
|
||||
void Update(TEntity entity);
|
||||
}
|
||||
|
||||
public interface IEditableRepository<TEntity> : IRepository<TEntity, Guid>
|
||||
where TEntity : class, IEntity<Guid>, ISoftDeletable, IVersioned, ILockable
|
||||
{
|
||||
Task<TEntity> GetEditableAsync(Guid id, long? expectedVersion, CancellationToken ct = default);
|
||||
Task SoftDeleteAsync(Guid id, long? expectedVersion, CancellationToken ct = default);
|
||||
Task EnsureUniqueAsync(Expression<Func<TEntity, bool>> predicate, string errorMessage, CancellationToken ct = default);
|
||||
}
|
||||
|
||||
public interface IHistoryRepository<TEntity> : IRepository<TEntity, Guid>
|
||||
where TEntity : class, IEntity<Guid>, IHistoryEntry
|
||||
{
|
||||
Task AppendAsync(TEntity entry, CancellationToken ct = default);
|
||||
}
|
||||
|
||||
public interface IUnitOfWork
|
||||
{
|
||||
Task<int> SaveChangesAsync(CancellationToken ct = default);
|
||||
Task ExecuteInTransactionAsync(Func<CancellationToken, Task> action, CancellationToken ct = default);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace MiGu.DB.Abstractions.Providers;
|
||||
|
||||
public interface IDbProviderSetup
|
||||
{
|
||||
string Name { get; }
|
||||
void Configure(DbContextOptionsBuilder builder, string connectionString);
|
||||
string MigrationsAssemblyName { get; }
|
||||
string MigrationsNamespace { get; }
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace MiGu.DB.Abstractions.Runtime;
|
||||
|
||||
public interface IActorContext
|
||||
{
|
||||
string Name { get; }
|
||||
}
|
||||
|
||||
public interface IActorContextAccessor
|
||||
{
|
||||
IActorContext Current { get; set; }
|
||||
}
|
||||
|
||||
public interface IDataMigrator
|
||||
{
|
||||
int Order { get; }
|
||||
string Name { get; }
|
||||
Task MigrateAsync(DbContext db, CancellationToken ct = default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动期 Schema 初始化策略。
|
||||
/// <see cref="Migrate"/>:版本化迁移(发版/现场);
|
||||
/// <see cref="EnsureCreated"/>:按当前模型建库(开发期,改模型需删库重建)。
|
||||
/// </summary>
|
||||
public enum MiGuSchemaMode
|
||||
{
|
||||
Migrate = 0,
|
||||
EnsureCreated = 1
|
||||
}
|
||||
|
||||
public sealed class MiGuDbOptions
|
||||
{
|
||||
public string Provider { get; set; } = "sqlite";
|
||||
public string ConnectionString { get; set; } = "";
|
||||
public string ContentRootPath { get; set; } = "";
|
||||
|
||||
/// <summary>Schema 初始化模式,对应配置 Database:SchemaMode。</summary>
|
||||
public MiGuSchemaMode SchemaMode { get; set; } = MiGuSchemaMode.Migrate;
|
||||
|
||||
/// <summary>为 true 时,Schema 初始化后按 Order 执行全部 IDataMigrator(默认开启)。</summary>
|
||||
public bool ApplyDataMigratorsOnStartup { get; set; } = true;
|
||||
}
|
||||
Reference in New Issue
Block a user