- 为全部 5 个项目(Avalonia-API、Avalonia-Common、Avalonia-EFCore、 Avalonia-PC、Avalonia-Services)中缺失注释的类、方法、属性、字段、 接口成员等补全中文 XML 文档注释 - 共修改约 37 个文件,补全约 220+ 处注释 - 修复 ServiceEndpointCollection.cs 中 MapDelete<TService> 语法错误 - 修复 PcAuthService.cs 中 const prefix 位置错乱导致编译失败的问题 - 扫描结果:缺失项 0 - 构建结果:4/4 项目编译通过
116 lines
4.3 KiB
C#
116 lines
4.3 KiB
C#
using Microsoft.EntityFrameworkCore;
|
||
using System;
|
||
using System.Linq;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace Avalonia_EFCore.Database
|
||
{
|
||
/// <summary>
|
||
/// 应用数据库上下文基类 —— 自动根据 DatabaseConfiguration 选择数据库提供程序。
|
||
/// 所有业务 DbContext 继承此类即可获得多数据库支持。
|
||
/// </summary>
|
||
public abstract class AppDbContext(DatabaseConfiguration dbConfig) : DbContext
|
||
{
|
||
/// <summary>
|
||
/// 数据库配置。
|
||
/// </summary>
|
||
private readonly DatabaseConfiguration _dbConfig = dbConfig;
|
||
|
||
/// <summary>
|
||
/// 配置数据库提供程序和连接选项。
|
||
/// </summary>
|
||
/// <param name="optionsBuilder">选项构建器。</param>
|
||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||
{
|
||
if (optionsBuilder.IsConfigured) return;
|
||
|
||
ConfigureProvider(optionsBuilder, _dbConfig);
|
||
|
||
if (_dbConfig.EnableDetailedLog)
|
||
{
|
||
optionsBuilder.LogTo(Console.WriteLine, Microsoft.Extensions.Logging.LogLevel.Information);
|
||
}
|
||
|
||
// 启用详细的 EF Core 错误信息
|
||
optionsBuilder.EnableDetailedErrors();
|
||
optionsBuilder.EnableSensitiveDataLogging(_dbConfig.EnableDetailedLog);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据配置选择数据库提供程序。
|
||
/// 使用注册模式,由宿主项目注册具体的提供程序实现。
|
||
/// </summary>
|
||
public static void ConfigureProvider(DbContextOptionsBuilder optionsBuilder, DatabaseConfiguration config)
|
||
{
|
||
if (DatabaseProviderRegistry.TryGet(config.Provider, out var configurator))
|
||
{
|
||
configurator(optionsBuilder, config.ConnectionString, config.Timeout);
|
||
}
|
||
else
|
||
{
|
||
throw new NotSupportedException(
|
||
$"数据库提供程序 {config.Provider} 未注册。" +
|
||
$"请在宿主项目中安装对应的 EF Core NuGet 包并调用 DatabaseProviderRegistry.Register()。");
|
||
}
|
||
|
||
optionsBuilder.EnableDetailedErrors();
|
||
optionsBuilder.EnableSensitiveDataLogging(config.EnableDetailedLog);
|
||
|
||
if (config.EnableDetailedLog)
|
||
{
|
||
optionsBuilder.LogTo(Console.WriteLine, Microsoft.Extensions.Logging.LogLevel.Information);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 保存时自动设置时间戳。
|
||
/// </summary>
|
||
public override int SaveChanges(bool acceptAllChangesOnSuccess)
|
||
{
|
||
SetTimestamps();
|
||
return base.SaveChanges(acceptAllChangesOnSuccess);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 异步保存更改,自动设置时间戳。
|
||
/// </summary>
|
||
/// <param name="acceptAllChangesOnSuccess">是否在成功时接受所有更改。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>受影响的行数。</returns>
|
||
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
|
||
{
|
||
SetTimestamps();
|
||
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 自动设置新增或修改实体的 CreatedAt 和 UpdatedAt 时间戳。
|
||
/// </summary>
|
||
private void SetTimestamps()
|
||
{
|
||
var entries = ChangeTracker.Entries()
|
||
.Where(e => e.State == EntityState.Added || e.State == EntityState.Modified);
|
||
|
||
foreach (var entry in entries)
|
||
{
|
||
var entity = entry.Entity;
|
||
|
||
// 使用反射设置 CreatedAt / UpdatedAt(如果存在)
|
||
var createdAtProp = entity.GetType().GetProperty("CreatedAt");
|
||
var updatedAtProp = entity.GetType().GetProperty("UpdatedAt");
|
||
|
||
if (entry.State == EntityState.Added && createdAtProp != null)
|
||
{
|
||
createdAtProp.SetValue(entity, DateTime.UtcNow);
|
||
}
|
||
|
||
if (updatedAtProp != null)
|
||
{
|
||
updatedAtProp.SetValue(entity, DateTime.UtcNow);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|