DbTable是为了提供类似DataTable的轻量级数据集而设计,作为数据载体,只有列名、列类型和数据。DbTable 已经成为XCode数据查询的标准。
Nuget包:NewLife.Core
源码:https://github.com/NewLifeX/X/blob/master/NewLife.Core/Data/DbTable.cs
视频:https://www.bilibili.com/video/BV1xG411E7C7
基本结构
DbTable主要成员如下:
/// <summary>数据列</summary> public String[] Columns { get; set; } /// <summary>数据列类型</summary> [XmlIgnore, IgnoreDataMember] public Type[] Types { get; set; } /// <summary>数据行</summary> public IList<Object[]> Rows { get; set; } /// <summary>总行数</summary> public Int32 Total { get; set; }
Columns 存放数据集所有列名;
Types 存放每个列的类型;
Rows 存放数据行,每一行数据是Object数组;
这些内容构成了数据表的基本结构,在高效读写数据的场合,相比DataTable完全胜出。
数据访问
通过接口方法可以访问某一行某一列数据
/// <summary>读取指定行的字段值</summary> /// <typeparam name="T"></typeparam> /// <param name="row"></param> /// <param name="name"></param> /// <returns></returns> public T Get<T>(Int32 row, String name); /// <summary>尝试读取指定行的字段值</summary> /// <typeparam name="T"></typeparam> /// <param name="row"></param> /// <param name="name"></param> /// <param name="value"></param> /// <returns></returns> public Boolean TryGet<T>(Int32 row, String name, out T value); /// <summary>根据名称找字段序号</summary> /// <param name="name"></param> /// <returns></returns> public Int32 GetColumn(String name);
也可以枚举DbTable,直接访问数据行
var dt = new DbTable(); foreach(DbRow row in dt) { // row[2] // row["Name"] }
数据库读取
DbTable支持从数据库IDataReader中读取数据,这里也是XCode查询数据后构建DbTable的核心所在。
/// <summary>读取数据</summary> /// <param name="dr"></param> public void Read(IDataReader dr); /// <summary>读取头部</summary> /// <param name="dr"></param> public void ReadHeader(IDataReader dr); /// <summary>读取数据</summary> /// <param name="dr">数据读取器</param> /// <param name="fields">要读取的字段序列</param> public void ReadData(IDataReader dr, Int32[] fields = null);
二进制读写
DbTable支持二进制读写,实现备份与还原等功能。魔方的备份与还原基于该功能实现。
/// <summary>写入数据流</summary> /// <param name="stream"></param> public void Write(Stream stream); /// <summary>转数据包</summary> /// <returns></returns> public Packet ToPacket(); /// <summary>保存到文件</summary> /// <param name="file"></param> /// <param name="compressed">是否压缩</param> /// <returns></returns> public void SaveFile(String file, Boolean compressed = false); /// <summary>从数据流读取</summary> /// <param name="stream"></param> public void Read(Stream stream); /// <summary>读取</summary> /// <param name="pk"></param> /// <returns></returns> public Boolean Read(Packet pk); /// <summary>从文件加载</summary> /// <param name="file"></param> /// <param name="compressed">是否压缩</param> /// <returns></returns> public Int64 LoadFile(String file, Boolean compressed = false);
DbTable可以整体备份到文件,然后异地恢复,或者序列化为数据流,通过网络传输到其它地方。这是XCode实现RPC查询的关键,sql作为参数,DbTable作为结果返回。
Json序列化
DbTable支持转为字典数组形式,并转为Json格式
/// <summary>转Json字符串</summary> /// <param name="indented">是否缩进。默认false</param> /// <param name="nullValue">是否写空值。默认true</param> /// <param name="camelCase">是否驼峰命名。默认false</param> /// <returns></returns> public String ToJson(Boolean indented = false, Boolean nullValue = true, Boolean camelCase = false); /// <summary>转为字典数组形式</summary> /// <returns></returns> public IList<IDictionary<String, Object>> ToDictionary();
模型类反射
XCode的数据访问层DAL支持Mapper写法,类似Dapper用法,实际上借助了DbTable的模型类反射能力。
/// <summary>数据表转模型列表。普通反射,便于DAL查询后转任意模型列表</summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public IEnumerable<T> ReadModels<T>(); /// <summary>写入模型列表</summary> /// <typeparam name="T"></typeparam> /// <param name="models"></param> public void WriteModels<T>(IEnumerable<T> models);
ReadModels用于把DbTable转为对象数组,内部动态创建模型实例,并反射赋值给对应的属性。
WriteModels用于把一批对象写入到DbTable里,因此,DbTable可以作为对象集合到二进制数据或Json数据的桥梁。
总结
DbTable 在NewLife数据处理体系中具有举足轻重的地位,是各个方向数据交换的标准。