`

C++山寨C#中的DataTable

阅读更多
原帖地址:http://www.cnblogs.com/hlxs/archive/2013/05/31/3110036.html

简单介绍一下DataTable。DataTable主要基于表、行、单元格。行用集合包装单元格,表用集合包装行,大致就是这样。DataColumn表示单元格,DataColumn中的字段还挺多的,在实际应用中我们可能只想用它来存一个int型的数据;DataColumnCollection中用一个ArrayList封装DataColumn,表示一些单元格的集合;DataRow直接在DataColumnCollection的基础上提供一些方法,成为行记录。而DataRowCollection则用集合的方式封装DataRow成为表,但它不是以线性、链表等方式,而是基于红黑树RBTree<DataRow>,主要是查询和删除比较方便,而DataTable则是DataRowCollection的封装,对看了DataTable整个实现的大致代码,我不得吐槽一下:这它妈是把牛刀,我们每天用它来切菜,用着还挺方便。DataTable提供了很强大的功能,但是我们基本不需要,有时候基本上是得到一个DataTable,啥都不做,直接绑定,最常用的也就Update和Insert,Select和Delete则次之。当然你会说避免使用DataTable,当然还有人说C#......


OK废话到此结束,今天我想做说的是用C++来实现DataTable。大致思路还是按照C#中的来,功能没有C#中的强大,但增删改查的功能还是有的,基本还是个人练习,把代码放出来跟大家讨论一下。基本上是STL中几个集合的运用。在我的实现在并没有使用红黑树,而是用list<DataRow*>代替了,主要类的头文件如下:


DataColumn的实现代码如下,主要是对几个字段的封装。源码共享



#pragma once
class DataTable;
#include
<iostream>
using namespace std;

template
<typename T>
class TDataColumn
{
public:
TDataColumn():columnName(
string()),caption(string())
{

}

TDataColumn(
const string& _columnName):columnName(_columnName),caption(string())
{

}

virtual ~TDataColumn()
{

}

void Caption(const string& _caption)
{
caption
=_caption;
}
string Caption()
{
return caption.size() ?caption:columnName;
}

void ColumnName(const string& _columnName)
{
columnName
=_columnName;
}
string ColumnName()
{
return columnName;
}

void Value(const T& _value)
{
value
=_value;
}
T Value()
{
return value;
}

int ObjectId()
{
return objectId;
}

void Table(DataTable* tb)
{
table
=tb;
}

DataTable
* Table()
{
return table;
}

string TypeName()
{
return typeid(T).name();
}

protected:
int objectId;
string columnName;
string caption;
T value;
DataTable
* table;
};


class DataColumn:public TDataColumn<string>
{
public:
friend
class DataColumnCollection;
friend
class DataTable;
DataColumn():TDataColumn
<string>()
{
objectId
=++objectCountId;
}

DataColumn(
const DataColumn& dc)
{
*this=dc;
}

DataColumn
& operator=(const DataColumn& dc)
{
objectId
=++objectCountId;
columnName
=dc.columnName;
caption
=dc.caption;
value
=dc.value;
table
=dc.table;
return *this;
}

DataColumn(
const string& _columnName):TDataColumn<string>(_columnName)
{
objectId
=++objectCountId;
}

bool operator==(const DataColumn& dc)
{
return objectId==dc.objectId;
}

bool operator!=(const DataColumn& dc)
{
return objectId!=dc.objectId;
}

bool operator<(const DataColumn& dc)
{
return objectId<dc.objectId;
}

bool operator>(const DataColumn& dc)
{
return objectId>dc.objectId;
}

void Show()
{
cout
<<"columnName:"<<columnName.data()<<",caption:"<<Caption().c_str()<<",value:"<<value.data()<<endl;
}

private:
static volatile int objectCountId;
};



其他文件的头文件如下:



#pragma once
#include
<iostream>
using namespace std;
#include
<assert.h>
#include
<vector>
#include
<list>
#include
<map>
#include
"DataColumn.h"
#include
"StringHelper.h"

class DataColumnCollection;
class DataRow;
class DataRowCollection;
class DataTable;

class DataColumnCollection
{
public:
friend
class DataTable;
friend
class DataRow;
friend
class DataRowCollection;
DataColumnCollection(DataTable
* table);
~DataColumnCollection();
void Add(DataColumn* dc);
void Add(DataColumn* dc,size_t index);

DataColumn
& Add(const string& columnName);

bool Contains(const string& columnName);
void Clear();
size_t Count();
int IndexOf(const string& columnName);

void Remove(DataColumn& dc);
void Remove(const string& columnName);
void RemoveAt(size_t index);

void CopyTo(DataColumnCollection* arr, size_t index);

DataColumn
& operator[](size_t index);
DataColumn
& operator[](const string& columnName);

void Table(DataTable* tb);
DataTable
* Table();
private:
void Add(DataColumn* dc,size_t index,DataColumnCollection* collect);
void RemoveAt(size_t index,DataColumnCollection* collect);
void InitData();
DataColumnCollection();
vector
<DataColumn*> dlist;
map
<int,DataColumn*> nameList;
DataTable
* table;
};

class DataRow
{
public:
friend
class DataTable;
friend
class DataRowCollection;
friend
class DataColumnCollection;
~DataRow();
void Table(DataTable* tb);
DataTable
* Table();

DataColumnCollection
& Columns();
DataColumn
& operator[](size_t index);
DataColumn
& operator[](const string& columnName);
bool operator=(const DataRow& dr);
private:
DataRow();
void Remove(DataColumn& dc);
void RemoveAt(size_t index);
DataColumnCollection
* columns;
DataTable
* table;
int rowId;
static volatile int rowIdCount;
};

class DataRowCollection
{
public:
friend
class DataTable;
friend
class DataColumnCollection;
DataRowCollection(DataTable
* table);
~DataRowCollection();
void Add(DataRow* dc);
void Clear();
size_t Count();
void Remove(DataRow* dc);
void RemoveAt(size_t index);
DataRow
& operator[](size_t index);
void Table(DataTable* tb);
DataTable
* Table();
private:
DataRowCollection();
list
<DataRow*> drlist;
DataTable
* table;
};


class DataTable
{
public:
friend
class DataColumnCollection;
friend
class DataRowCollection;
DataTable();
DataTable(
const string& _tableName);
~DataTable();

DataColumnCollection
& Columns();
DataRowCollection
& Rows();

string TableName();
void TableName(const string& _tableName);
DataRow
& operator[](size_t index);
void Clear();
DataRow
* NewRow();
vector
<DataRow*>* Select(const string& columnName,const string& value) ;
private:
void InitData();
DataColumnCollection
* dcCollect;
DataRowCollection
* drCollect;
string tableName;
};


测试代码如下:



#include <iostream>
using namespace std;
#include
<sstream>
#include
"DataColumn.h"
#include
"DataTable.h"
#include
"OperationTimer.h"

int main( )
{
DataTable dt;
for(size_t i=0;i<10;i++)
{
string s("column");
s.push_back(
char('0'+i));
DataColumn
*dc=new DataColumn(s);
dt.Columns().Add(dc);
}

for(int j=0;j<10;j++)
{
DataRow
* dr=dt.NewRow();
for(int i=0;i<10;i++)
{
string s("row");
s.push_back(
char('0'+j));
s.push_back(
char('0'+i));
(
*dr)[i].Value(s) ;
}
dt.Rows().Add(dr);
}

int rowCount=dt.Rows().Count();
int columnCount=dt.Columns().Count();
cout
<<""<<rowCount<<""<<columnCount<<""<<endl;
rowCount
=rowCount/2;
columnCount
=columnCount/2;
cout
<<""<<rowCount<<""<<columnCount<<"列的值为:"<<dt[rowCount][columnCount].Value().c_str()<<endl;

dt.Columns().Add(
new DataColumn("column10"));
dt.Columns().Add(
new DataColumn("column11"));
cout
<<"新增两列后:"<<endl;
rowCount
=dt.Rows().Count();
columnCount
=dt.Columns().Count();
cout
<<""<<rowCount<<""<<columnCount<<""<<endl;
rowCount
=rowCount/2;
columnCount
=columnCount/2;
cout
<<""<<rowCount<<""<<columnCount<<"列的值为:"<<dt[rowCount][columnCount].Value().c_str()<<endl;
cout
<<"删除一行一列后:"<<endl;
dt.Columns().RemoveAt(
4);
dt.Rows().RemoveAt(
2);

rowCount
=dt.Rows().Count();
columnCount
=dt.Columns().Count();
cout
<<""<<rowCount<<""<<columnCount<<""<<endl;
rowCount
=rowCount/2;
columnCount
=columnCount/2;
cout
<<""<<rowCount<<""<<columnCount<<"列的值为:"<<dt[rowCount][columnCount].Value().c_str()<<endl<<endl;

cout
<<"查询列名为column3,值为row43的行,数据如下:"<<endl;
vector
<DataRow*>* vect=dt.Select("column3","row43");
for(size_t i=0;i<vect->size();i++)
{
DataColumnCollection
& dcCollect= (*vect)[i]->Columns();
for(size_t j=0;j<dcCollect.Count();j++)
{
dcCollect[j].Show();
}
}
delete vect;



getchar();
return 0;
}


 结构截图:


本文链接

分享到:
评论

相关推荐

    C# 中DataTable转换文本

    利用C#saveFileDialog控件,把DataTable中的数据保存输出的文本格式

    JAVA实现类似C#的DataTable数据结构_适用于安卓

    在Java开发中,特别是在Android应用开发中,常常需要处理数据集合,C#中的DataTable是一种非常方便的数据结构,它允许我们动态地存储和操作表格数据。然而,Java原生API并没有提供与之对应的类。这篇博客(博文链接...

    C#从datatable到listview的方法

    在C#编程中,将数据从DataTable对象转换到ListView控件是一种常见的数据展示技术,尤其在Windows Forms应用程序中。此过程涉及多个步骤,确保数据能够准确无误地从数据库或数据源传递到用户界面,从而提供清晰、有序...

    C# datatable删除多行

    在C#编程中,DataTable是System.Data命名空间中的一个类,它用于存储和操作数据集中的数据表。在处理大量数据时,有时我们需要删除DataTable中的特定行或多行。本篇将详细介绍如何在C#中有效地实现DataTable的多行...

    C# winform打印DataTable数据

    本文将深入探讨如何使用C# WinForms来打印DataTable中的数据。 首先,要实现这个功能,我们需要引入必要的组件。在C# WinForms中,`PrintDocument`组件是用于处理打印任务的核心类,而`PrintPreviewDialog`则可以...

    C#中DataSet和DataTable的基本用法与常见操作

    内容概要:本文详细介绍了 C# 中 DataSet 和 DataTable 的基本概念、区别及其常见的操作方法。首先,解释了 DataSet 和 DataTable 的不同之处,其中 DataSet 是数据集,可以包含多个 DataTable,而 DataTable 是数据...

    C#根据DataTable的数据变更动态生成SQL语句保存到数据库

    根据DataTable中数据行记录改变的状态,动态生成SQL语句, 如果一个表中字段上百个,在只改了其中两三个字段时,则生成的SQL语句就只会含有这修改内容的字段, 有了这一个函数,从此彻底告别手动写SQL语句更新到...

    C#将DataTable转化为List&lt;T&gt;

    在C#开发中,将DataTable转换为List泛型集合是一个常见的需求,特别是在使用三层架构进行网站开发时,我们可能会从数据访问层获取一个DataTable对象,然后需要将其转换为一个强类型的List集合以便在业务逻辑层或表示...

    C#中替换DataSet中DataTable列名的三种思路和方法.rar

    在C#编程中,处理数据通常会涉及到对DataSet和DataTable对象的操作。DataSet是.NET Framework中的一个强大组件,它用于存储和操作离线数据,而DataTable则代表了一个表格型的数据集。在某些场景下,我们可能需要修改...

    C# Datatable数据Excel导出和行列转换

    ### C# 中 DataTable 数据到 Excel 的导出及行列转换 #### 一、概述 在实际开发过程中,我们经常需要将数据库中的数据导出为 Excel 文件,以便于数据分析或分享给其他人。同时,在某些场景下还需要对数据进行行列...

    用C#实现对DataTable的JOIN,GROUP BY,FILTER,UNIONALL,DISTINCT

    用C#实现对DataTable的JOIN,GROUP BY,FILTER,UNIONALL,DISTINCT

    C#中表达式的计算 DataTable.Compute方法使用实例

    DataTable.Compute方法使用实例 DataTable.Compute强大的功能 C#中表达式的计算 详细说明:http://www.our-code.com/news/2010718/n458047.html

    C#-DataTable操作类

    C#-DataTable操作类(添加自增列、检查是否为数据行、DataTable转换为List、List转换为DataTable,DataTable排序、DataRow转自定义实体)

    C# 两个datatable中的数据快速比较返回交集 并集或差集

    在C#编程中,DataTable是一种常用的结构,用于存储和操作数据,类似于数据库表格。当我们处理多个DataTable时,可能需要比较它们之间的数据,找出交集、并集或差集。这在数据分析、数据清洗或者数据库同步等场景中...

    C# DataTable去重,根据列名去重保留其他列

    详细描述如何使用C# 去除DataTable中的重复列,根据列名去重保留其他列

    c# 对DataTable各种常用操作的源代码

    附件包括 c# 对 DataTable各种常用操作的源代码 包括DataTable按起始位置和移动及移动方向进行移动并返回新的DataTable ;根据条件过滤表 ;返回两个表的关联数据,关联后的表中只包含第一个表的字段和第二个表需要...

    C# DataTable 转换为 实体类对象实例

    } } //对应数据库表: //User //字段:ID、Name 那么你也许需要编写将DataTable 转换为实体对象的方法,便利DataTable.Rows 获得并填充。。 下面是我写的一个通用方法,分享+记录,便于日后直接Copy ~ 代码如下:...

    DataTable 自定义打印(c#)

    本文将详细讲解如何在C#环境中实现DataTable的自定义打印,特别是针对DataGridView的打印。 首先,理解“自定义打印”意味着我们需要控制打印的内容、样式以及布局,而不仅仅是简单的屏幕视图的复制。在.NET中,...

    C# DataTable行转列

    C# DataTable行转列 可能从数据库读出来的数据需要转换下行列来显示、在SQL里转换占用SQL资源 放在界面用C#转换可能更好 这是个简单的例子 原来显示: 年级 班级 人数 转换为: 年级 一班 二班 三班 合计

    C#中datatable去重的方法

    本文实例讲述了C#中datatable去重的方法,分享给大家供大家参考。具体方法如下: 这里主要介绍两种方法: 1 数据库直接去除重复 代码如下:select distinct * from 表名 去除了重复行distinct 2 对 DataTable直接...

Global site tag (gtag.js) - Google Analytics