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数据处理体系中具有举足轻重的地位,是各个方向数据交换的标准。