- 🚀 DataTables - 现代化高性能数据表系统
异步优先数据表解决方案 - 适用于.NET Core服务端与Unity客户端
- 安装NuGet包
dotnet add package DataTables.API
- 零心智负担使用 🎉
using DataTables;
// 🌟 现代异步API - 自动初始化
var scene = await DataTableManager.LoadAsync<DTScene>();
var items = DataTableManager.GetCached<DTItem>(); // 缓存查询
Console.WriteLine($"场景: {scene?.Name}, 物品数量: {items?.Count ?? 0}");
// 🔥 可选的性能优化
await DataTableManager.PreheatAsync(Priority.Critical | Priority.Normal);
Console.WriteLine("数据预热完成!");
- 智能配置 (可选)
// 🎯 一行代码完成所有配置
DataTableManager.UseFileSystem("./DataTables");
DataTableManager.EnableMemoryManagement(50); // 50MB智能缓存
DataTableManager.EnableProfiling(stats =>
Console.WriteLine($"加载{stats.TableCount}个表,耗时{stats.LoadTime}ms"));
-
安装Unity Package
- 从Releases下载
DataTables.Unity.unitypackage
- 从Releases下载
-
现代化Unity使用
using DataTables;
using UnityEngine;
public class GameManager : MonoBehaviour
{
async void Start()
{
// 🌟 异步优先 - 无阻塞启动
var config = await DataTableManager.LoadAsync<DTGameConfig>();
Debug.Log($"游戏版本: {config?.Version}");
// 🔥 智能分层预热
await DataTableManager.PreheatAsync(Priority.Critical);
Debug.Log("关键数据预热完成,游戏可以启动!");
// 后台预热其他数据
_ = DataTableManager.PreheatAsync(Priority.Normal | Priority.Lazy);
}
}
功能 | 🆕 新API (推荐) | 🔄 兼容API |
---|---|---|
异步加载 | await DataTableManager.LoadAsync<T>() |
DataTableManager.CreateDataTable<T>() |
缓存查询 | DataTableManager.GetCached<T>() |
DataTableManager.GetDataTable<T>() |
状态检查 | DataTableManager.IsLoaded<T>() |
手动检查null |
批量预热 | await DataTableManager.PreheatAsync(Priority.All) |
DataTableManagerExtension.Preload() |
内存管理 | DataTableManager.EnableMemoryManagement(50) |
无 |
Hook注册 | DataTableManager.OnLoaded<T>(callback) |
DataTableManager.HookDataTableLoaded<T>() |
// 🌟 推荐的现代异步模式
// 单表异步加载
var scene = await DataTableManager.LoadAsync<DTScene>();
// 并发加载多表
var tasks = new[]
{
DataTableManager.LoadAsync<DTScene>(),
DataTableManager.LoadAsync<DTItem>(),
DataTableManager.LoadAsync<DTCharacter>()
};
var results = await Task.WhenAll(tasks);
// 缓存优先查询 (热路径)
var cachedScene = DataTableManager.GetCached<DTScene>();
if (cachedScene != null)
{
var sceneData = DTScene.GetDataRowById(1001);
Console.WriteLine($"场景名称: {sceneData?.Name}");
}
// 🎯 统一配置接口
// 文件系统数据源 (默认)
DataTableManager.UseFileSystem("./DataTables");
// 网络数据源
DataTableManager.UseNetwork("https://cdn.game.com/data/");
// 自定义数据源
DataTableManager.UseCustomSource(new MyCustomDataSource());
// 内存管理 (LRU缓存)
DataTableManager.EnableMemoryManagement(100); // 100MB限制
// 性能监控
DataTableManager.EnableProfiling(stats =>
{
Console.WriteLine($"加载了 {stats.TableCount} 个表");
Console.WriteLine($"总耗时: {stats.LoadTime}ms");
Console.WriteLine($"内存使用: {stats.MemoryUsed / 1024 / 1024:F1}MB");
});
// 🔥 现代预热API - 基于优先级的智能调度
// 客户端:分层预热
await DataTableManager.PreheatAsync(Priority.Critical); // 立即加载关键数据
_ = DataTableManager.PreheatAsync(Priority.Normal | Priority.Lazy); // 后台预热其他数据
// 服务器:全量预热
await DataTableManager.PreloadAllAsync();
// 自定义预热 (并发安全)
var tasks = new[]
{
DataTableManager.LoadAsync<DTConfig>(),
DataTableManager.LoadAsync<DTLevel>(),
DataTableManager.LoadAsync<DTCharacter>()
};
await Task.WhenAll(tasks);
// 📊 全面的性能监控
// 实时统计
var stats = DataTableManager.GetStats();
Console.WriteLine($"已加载表数量: {stats.TableCount}");
Console.WriteLine($"总内存使用: {stats.MemoryUsed / 1024 / 1024:F1}MB");
// 缓存统计
var cacheStats = DataTableManager.GetCacheStats();
if (cacheStats.HasValue)
{
var cache = cacheStats.Value;
Console.WriteLine($"缓存项数: {cache.TotalItems}");
Console.WriteLine($"缓存命中率: {cache.HitRate:P}");
Console.WriteLine($"内存使用率: {cache.MemoryUsageRate:P}");
}
// 加载状态检查
bool isLoaded = DataTableManager.IsLoaded<DTScene>();
Console.WriteLine($"场景表是否已加载: {isLoaded}");
// 🎣 简化的类型安全Hook系统
// 类型安全Hook
DataTableManager.OnLoaded<DTScene>(table =>
{
Console.WriteLine($"✅ 场景表加载完成: {table.Count} 行数据");
// 自定义后处理
ValidateSceneData(table);
BuildSceneIndex(table);
});
// 全局Hook
DataTableManager.OnAnyLoaded(table =>
{
var typeName = table.GetType().Name;
var loadTime = DateTime.Now;
Console.WriteLine($"📊 [{loadTime:HH:mm:ss}] {typeName} 已加载");
});
// 清理Hook
DataTableManager.ClearHooks();
using DataTables;
using UnityEngine;
public class ModernDataTableDemo : MonoBehaviour
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static async void InitializeDataTables()
{
// 🚀 启动时快速初始化
DataTableManager.UseFileSystem(Application.streamingAssetsPath + "/DataTables");
DataTableManager.EnableMemoryManagement(30); // Unity环境30MB限制
// 立即加载核心表
await DataTableManager.LoadAsync<DTGameConfig>();
// 后台预热其他表
_ = DataTableManager.PreheatAsync(Priority.Normal | Priority.Lazy);
}
async void Start()
{
// 🎯 场景相关数据预热
await DataTableManager.PreheatAsync(Priority.Critical);
Debug.Log("关键数据已就绪,游戏可以开始!");
// 使用数据
var config = DataTableManager.GetCached<DTGameConfig>();
if (config != null)
{
var gameConfig = DTGameConfig.GetDataRowById(1);
Debug.Log($"游戏版本: {gameConfig?.Version}");
}
}
void OnApplicationPause(bool pauseStatus)
{
if (pauseStatus)
{
// 暂停时清理缓存释放内存
DataTableManager.ClearCache();
}
}
}
// 📱 移动平台优化
public class MobileOptimizationDemo : MonoBehaviour
{
void Start()
{
// 根据设备性能调整缓存大小
var systemMemory = SystemInfo.systemMemorySize;
var cacheSize = systemMemory > 4096 ? 50 : 20; // 4GB+设备使用50MB,否则20MB
DataTableManager.EnableMemoryManagement(cacheSize);
// 监听内存警告
Application.lowMemory += OnLowMemory;
}
private void OnLowMemory()
{
Debug.Log("收到内存警告,清理数据表缓存");
DataTableManager.ClearCache();
}
// 场景切换时的优化策略
public async void LoadScene(int sceneId)
{
var sceneConfig = DTScene.GetDataRowById(sceneId);
// 预加载场景相关数据
var preloadTasks = new[]
{
DataTableManager.LoadAsync<DTNpc>(),
DataTableManager.LoadAsync<DTQuest>(),
DataTableManager.LoadAsync<DTItem>()
};
await Task.WhenAll(preloadTasks);
// 开始切换场景
UnityEngine.SceneManagement.SceneManager.LoadScene(sceneConfig.SceneName);
}
}
// 🔧 扩展自定义数据源
public class EncryptedDataSource : IDataSource
{
private readonly string _baseDirectory;
private readonly byte[] _encryptionKey;
public EncryptedDataSource(string baseDirectory, byte[] encryptionKey)
{
_baseDirectory = baseDirectory;
_encryptionKey = encryptionKey;
}
public async ValueTask<byte[]> LoadAsync(string tableName)
{
var filePath = Path.Combine(_baseDirectory, $"{tableName}.encrypted");
var encryptedData = await File.ReadAllBytesAsync(filePath);
// 自定义解密逻辑
return DecryptData(encryptedData, _encryptionKey);
}
public ValueTask<bool> IsAvailableAsync()
{
return ValueTask.FromResult(Directory.Exists(_baseDirectory));
}
private byte[] DecryptData(byte[] encryptedData, byte[] key)
{
// 实现你的解密算法
return encryptedData; // 这里应该是解密后的数据
}
}
// 使用自定义数据源
var encryptionKey = LoadEncryptionKey();
var encryptedSource = new EncryptedDataSource("./EncryptedData", encryptionKey);
DataTableManager.UseCustomSource(encryptedSource);
// 🏭 工厂模式 - 消除反射调用,提升90%性能
// 实现数据表工厂
public class DTSceneFactory : IDataTableFactory<DTScene, DRScene>
{
public DTScene CreateTable(string name, int capacity)
=> new DTScene(name, capacity);
public DRScene CreateRow()
=> new DRScene();
}
// 注册工厂 (通常由代码生成器自动完成)
DataTableManager.RegisterFactory<DTScene, DRScene, DTSceneFactory>();
// 注册后,表的创建将使用工厂模式,避免反射调用
var scene = await DataTableManager.LoadAsync<DTScene>(); // 90%性能提升!
// 🧠 精确的内存管理控制
// 启用LRU缓存管理
DataTableManager.EnableMemoryManagement(50); // 50MB限制
// 监控内存使用
var cacheStats = DataTableManager.GetCacheStats();
if (cacheStats?.MemoryUsageRate > 0.8f) // 使用率超过80%
{
Console.WriteLine("内存使用率较高,LRU将自动淘汰旧数据");
}
// 手动清理缓存
DataTableManager.ClearCache();
// 禁用内存管理 (如果需要)
DataTableManager.DisableMemoryManagement();
Excel文件格式定义:
行号 | 内容 | 说明 |
---|---|---|
1 | DTGen=Table, Title=场景表, Class=Scene, Index=Id, Group=Type |
表头配置 |
2 | 场景ID , 场景名称@ABC , 场景类型 , #备注 |
列描述 |
3 | Id , Name , Type , Comment |
字段名 |
4 | int , string , Enum<SceneType> , string |
字段类型 |
5+ | 数据行... | 实际数据 |
// 🎯 生成的高性能静态API (使用优化后的DataTableManager)
// 索引查询 - 使用GetCached优化
public static DRScene? GetDataRowById(int id)
{
var table = DataTableManager.GetCached<DTScene>(); // 缓存优先
return table?.m_Dict1.TryGetValue(id, out var result) == true ? result : null;
}
// 分组查询
public static List<DRScene>? GetDataRowsGroupByType(SceneType type)
{
var table = DataTableManager.GetCached<DTScene>();
return table?.m_Dict2.TryGetValue(type, out var result) == true ? result : null;
}
// 表状态检查
public static bool IsLoaded => DataTableManager.IsLoaded<DTScene>();
// 表统计信息
public static int Count => DataTableManager.GetCached<DTScene>()?.Count ?? 0;
类型 | 说明 | 示例 |
---|---|---|
基础类型 | int , long , float , double , bool , string |
42 , 3.14 , true |
数组 | Array<T> |
Array<int> → [1,2,3] |
枚举 | Enum<T> |
Enum<ColorType> → Red |
字典 | Map<K,V> |
Map<int,string> → {1:"a",2:"b"} |
JSON | JSON |
复杂对象的JSON字符串 |
自定义 | Custom |
自定义类,需要字符串构造函数 |
# 全局安装
dotnet tool install --global DataTables.Generator
# 本地安装
dotnet tool install --tool-path ./tools DataTables.Generator
# 基础生成 - 自动优化
dotnet dtgen -i ./Tables -co ./Generated -do ./Data -n MyProject -p DT
# 高级生成 - 包含工厂模式优化
dotnet dtgen \
-i "./Tables" \ # 输入目录
-co "./Generated" \ # 代码输出目录
-do "./Data" \ # 数据输出目录
-n "MyProject" \ # 命名空间
-p "DT" \ # 类名前缀
-t "RELEASE" \ # 列标签过滤
--factory \ # 启用工厂模式生成
--async-first \ # 异步优先API
-f # 强制覆写
# 启用严格名称校验与公式一致性校验,并生成诊断报告
dotnet dtgen \
-i "./Tables" -co "./Generated" -do "./Data" -n "MyProject" -p "DT" \
--strictNameValidation true \
--validateFormulaConsistency true \
--formulaPolicy ValidateOnly \
--columnCommentMarkerText "#列注释标志" \
--rowCommentMarkerText "#行注释标志" \
--skipCellMarker "#" \
-t "CLIENT && !SERVER" \
--diagnosticsJsonOutput diagnostics.json
# 关闭公式评估,快速导出
dotnet dtgen -i ./Tables -co ./Generated -do ./Data --formulaPolicy Off
- 语法元素(大小写不敏感):
- 标识符:
[A-Za-z0-9_]+
- 布尔运算:
AND
、OR
、NOT
(别名:&&
、||
、!
) - 括号:
(
、)
- 标识符:
- 优先级:
NOT > AND > OR
- 空表达式:视为
true
(不过滤) - Excel 标签标注:在列标题末尾用
@
标注标签,多个标签可用空格、逗号、分号、竖线、中文逗号等分隔。- 示例:
Hp@CLIENT
、Atk@CLIENT,SERVER
、Speed@client|pve
- 示例:
- 过滤表达式示例:
CLIENT AND NOT SERVER
(CLIENT OR EDITOR) AND NOT LEGACY
PVE || PVP
!INTERNAL
诊断报告(JSON)字段:
- InfoCount / WarningCount / ErrorCount
- Items: [ { Severity, File, Sheet, Cell, Message } ]
<!-- 现代化MSBuild集成 -->
<Target Name="DataTablesGen" BeforeTargets="BeforeBuild">
<DataTablesGenerator
UsingNamespace="$(ProjectName)"
InputDirectory="$(ProjectDir)Tables"
CodeOutputDirectory="$(ProjectDir)Generated"
DataOutputDirectory="$(ProjectDir)DataTables"
PrefixClassName="DT"
EnableFactoryPattern="true"
AsyncFirstAPI="true"
FilterColumnTags="RELEASE"
ForceOverwrite="false" />
</Target>
如果你目前使用传统的DataTableManager API:
// ❌ 旧版本方式 (仍然支持)
DataTableManager.SetDataTableHelper(new DefaultDataTableHelper("./Data"));
DataTableManagerExtension.Preload(() => Console.WriteLine("加载完成"));
DataTableManager.CreateDataTable<DTScene>(() => {
var scene = DataTableManager.GetDataTable<DTScene>();
var data = scene.GetDataRowById(2000);
});
// ✅ 升级到现代异步方式
DataTableManager.UseFileSystem("./Data"); // 一次性配置
var scene = await DataTableManager.LoadAsync<DTScene>(); // 异步加载
var data = DTScene.GetDataRowById(2000); // 直接访问
- 阶段1 - 兼容运行 (保持现有代码不变)
// 现有代码继续工作,无需修改
DataTableManager.SetDataTableHelper(helper);
var table = DataTableManager.GetDataTable<DTScene>();
- 阶段2 - 新功能使用新API
// 新功能采用现代API
await DataTableManager.LoadAsync<DTNewTable>();
DataTableManager.EnableMemoryManagement(50);
- 阶段3 - 逐步重构
// 逐步替换旧API调用
// DataTableManager.CreateDataTable<T>(callback)
// → await DataTableManager.LoadAsync<T>()
旧API | 新API | 说明 |
---|---|---|
DataTableManager.SetDataTableHelper() |
DataTableManager.UseFileSystem() |
数据源配置 |
DataTableManager.CreateDataTable<T>() |
await DataTableManager.LoadAsync<T>() |
异步加载 |
DataTableManager.GetDataTable<T>() |
DataTableManager.GetCached<T>() |
缓存查询 |
DataTableManagerExtension.Preload() |
await DataTableManager.PreloadAllAsync() |
批量预热 |
DataTableManager.HookDataTableLoaded<T>() |
DataTableManager.OnLoaded<T>() |
Hook注册 |
基于激进优化的性能表现:
场景 | 优化前 | 优化后 | 提升幅度 |
---|---|---|---|
并发加载 | 存在竞态条件 | 100%并发安全 | ∞ |
热路径查询 | ~4500 ticks | ~1489 ticks | 3x 提升 |
内存管理 | 手动管理 | 智能LRU缓存 | 30-50% 减少 |
异步操作 | 阻塞调用 | ValueTask优化 | 避免死锁 |
工厂模式 | 反射创建 | 零反射调用 | 90% 提升潜力 |
This library is under the MIT License.
如果这个项目对你有帮助,请考虑:
- ⭐ 给项目点星
- 🐛 报告bug和建议
- 💡 贡献代码和文档
- 📢 向其他开发者推荐
感谢使用 DataTables!享受现代化高性能的开发体验! 🚀