第17课:数据库操作基础——tDataHelpler类
开发工作中,可以将DataTable对象作为数据的中间格式,并转换为各种所需的格式,如HTML表格、HTML列表、JSONArray和JSONObject文本等格式;本课将封装tDataHelper类,其中包含了相关的转换工作。
DataTable转换HTML表元素
首先来看tDataHelper.GetTableHtml()方法的定义,如下面的代码(/app_code/data/base/tDataHelper.cs)。
C# |
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
public static class tDataHelper
{
// 在服务器端生成行操作,opt中的{0}替换为pkName中的行数据
public static string GetTableHtml(DataTable data,
string pkName, bool showPkColumn, string clientId, string opt)
{
if (data == null || data.Columns.Count<=0 ||
data.Rows.Count <= 0) return "";
// 处理主键
if (data.Columns.Contains(pkName))
data.Columns[pkName].SetOrdinal(0);
else
return "";
int colStartIndex = showPkColumn ? 0 : 1;
//
StringBuilder sb = new StringBuilder(3000);
sb.AppendFormat("<table class='table_normal' id='{0}'>", clientId);
// 标题行
sb.Append("<tr rownum='0'>");
for (int col = colStartIndex; col < data.Columns.Count; col++)
sb.AppendFormat("<th>{0}</th>", data.Columns[col].ColumnName);
sb.Append("<th>操作</th></tr>");
// 数据行
bool alternationRow = false;
for (int row = 0; row < data.Rows.Count; row++)
{
sb.AppendFormat("<tr {0} rownum='{1}' rowdata='{2}'>",
(alternationRow ? "class='alternation_row'" : ""),
row + 1, data.Rows[row][pkName]);
alternationRow = !alternationRow;
//
for (int col = colStartIndex; col < data.Columns.Count; col++)
{
sb.AppendFormat("<td>{0}</td>", data.Rows[row][col]);
}
// 行操作
sb.AppendFormat("<td>{0}</td>",
string.Format(opt, data.Rows[row][pkName]));
//
sb.Append("</tr>");
}
//
sb.Append("</table>");
//
return sb.ToString();
}
// 其它代码...
}
|
tDataHelper.GetTableHtml()方法需要五个参数,分别是:
- data,定义为DataTable对象,指定需要转换为HTML表元素(table)的数据。
- pkName,指定DataTable对象中的主键列名。
- showPkColumn,在HTML的表元素中是否显示主键列。
- clientId,设置table元素的id属性值。
- opt,设置每行的操作,其中的{0}会替换为行主键数据。
下面的代码演示了tDataHelper.GetTableHtml()方法的基本应用。
C# |
DataTable data =
tApp.Db.GetJet().GetTable("select * from user_main");
tWeb.Write(tDataHelper.GetTableHtml(data, "userid", true, "gv1"));
|
代码中读取了cdb_demo数据库中user_main表的全部内容,生成的HTML代码如下(省去userpwd字段数据)。
HTML |
<table class='table_normal' id='gv1'>
<tr rownum='0'>
<th>userid</th><th>username</th><th>userpwd</th><th>email</th><th>locked</th><th>操作</th>
</tr>
<tr rownum='1' rowdata='1'>
<td>1</td><td>user01</td><td>...</td><td>user01@aaa.bbb</td><td>0</td>
<td><a href='Edit.aspx?id=1'>编辑</a></td>
</tr>
<tr class='alternation_row' rownum='2' rowdata='2'>
<td>2</td><td>user02</td><td>...</td><td>user02@aaa.bbb</td><td>1</td>
<td><a href='Edit.aspx?id=2'>编辑</a></td>
</tr>
<tr rownum='3' rowdata='3'>
<td>3</td><td>user03</td><td>...</td><td>user03@xxx.yyy</td><td>0</td>
<td><a href='Edit.aspx?id=3'>编辑</a></td>
</tr>
<tr class='alternation_row' rownum='4' rowdata='4'>
<td>4</td><td>user04</td><td>...</td><td>user04@xxx.yyy</td><td>0</td>
<td><a href='Edit.aspx?id=4'>编辑</a></td>
</tr>
<tr rownum='5' rowdata='5'>
<td>5</td><td>user05</td><td>...</td><td>user05@xxx.yyy</td><td>0</td>
<td><a href='Edit.aspx?id=5'>编辑</a></td>
</tr>
</table>
|
可以看到,table元素中设置了class属性为table_normal,id为tDataHelper.GetTableHtml()方法的clientId属性指定。
table元素的第一行是列标题行,其中使用了th元素显示列名,并在最后一列显示“操作”。此外,标题行的tr元素中还设置了rownum属性为0。
数据行的tr元素中,使用rownum属性设置了从1开始的行号,rowdata属性设置每行的主键字段数据。每隔一行还会在tr元素中设置class属性为alternation_row。
图1是使用了一些CSS样式后的显示效果,其中,间隔行使用了浅黄色的背景。
图1
开发中,还可以根据需要创建GetTableHtml()方法的重载版本,后续课程中还会有相关讨论。
DataTable转JSON格式
数据交换过程中,JSON是一种简单易用的格式,在tDataHelper类中封装了GetJson()方法,用于将DataTable对象数据转换为JSON数据的文本格式,方法定义如下。
C# |
// 转换为JSON文本
public static string GetJson(DataTable data)
{
if (data == null || data.Columns.Count == 0 ||
data.Rows.Count == 0) return "";
//
StringBuilder sb = new StringBuilder("[", data.Rows.Count * 100);
// 数据行
for (int row = 0; row < data.Rows.Count; row++)
{
sb.Append("{");
sb.AppendFormat("\"{0}\":\"{1}\"",
data.Columns[0].ColumnName, data.Rows[row][0]);
for(int col = 1; col < data.Columns.Count; col++)
{
sb.AppendFormat(",\"{0}\":\"{1}\"",
data.Columns[col].ColumnName, data.Rows[row][col]);
}
sb.Append("},");
}
// 去掉最后一个逗号
sb.Remove(sb.Length - 1, 1);
//
sb.Append("]");
return sb.ToString();
}
|
tDataHelper.GetJson()方法的参数包括只需要指定需要转换的DataTable对象。方法中,会将DataTable对象中的数据转换为如下格式的JSON文本。
JSON |
[{...},{...},{...}...]
|
生成的文本中,整体数据定义为JSONArray格式,每行记录定义为一个JSONObject格式,即Dictionary或Map对象,其中的每个数据定义为“键/值”格式。
下面的代码会将用户表(user_main)中的数据转换为JSON文本格式。
C# |
using System;
using System.Data;
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DataTable data =
tApp.Db.GetJet().GetTable("select * from user_main");
tWeb.Write(tDataHelper.GetJson(data));
}
}
|
代码生成的内容如下。
JSON |
[
{"userid":"1","username":"user01",
"userpwd":"...","email":"user01@aaa.bbb","locked":"0"},
{"userid":"2","username":"user02",
"userpwd":"...","email":"user02@aaa.bbb","locked":"1"},
{"userid":"3","username":"user03",
"userpwd":"...","email":"user03@xxx.yyy","locked":"0"},
{"userid":"4","username":"user04",
"userpwd":"...","email":"user04@xxx.yyy","locked":"0"},
{"userid":"5","username":"user05",
"userpwd":"...","email":"user05@xxx.yyy","locked":"0"}
]
|
在客户端的JavaScript代码中,可以使用JSON.parse()方法将这些文本内容很方便地转换为JavaScript数组。
数组和tPairList转JSON
JSON是一种很灵活的格式,在数据交换过程中可以根据需要灵活应用,下面的代码,我们会在tDataHelper类中添加一些方法,分别将Array和tPairList数据转换为相应的JSON格式文本。
C# |
// Array转JSON数组
public static string GetJson(Array arr)
{
if (arr == null) return "";
StringBuilder sb = new StringBuilder("[", arr.Length * 10);
sb.AppendFormat("\"{0}\"", arr.GetValue(0));
for (int i = 1; i < arr.Length; i++)
sb.AppendFormat(",\"{0}\"", arr.GetValue(i));
sb.Append("]");
return sb.ToString();
}
// tPairList转JSON对象
public static string GetJson(tPairList lst)
{
if (lst == null) return "";
StringBuilder sb = new StringBuilder("{", lst.Count * 20);
sb.AppendFormat("\"{0}\":\"{1}\"",lst[0].Name,lst[0].Value);
for (int i = 1; i < lst.Count; i++)
sb.AppendFormat(",\"{0}\":\"{1}\"", lst[i].Name, lst[i].Value);
sb.Append("}");
return sb.ToString();
}
|
代码中,GetJson(Array)方法会将C#数组中的数据转换为JSONArray格式的文本内容,在JavaScript代码中可以通过JSON.parse()方法将文本内容转换为JavaScript数组。GetJson(tPairList)方法可以将封装的tPairList对象中的数据转换为JSONObject格式的文本内容,在JavaScript代码中同样可以使用JSON.parse()方法转换为JavaScript数组,并使用“键/值”格式访问数据。
更详细的JSON和JavaScript应用可以参考《网站全栈开发指南:HTML+CSS+JavaScript+PHP》或《网站全栈开发指南:HTML+CSS+JavaScript+ASP.NET》。
DataTable转HTML列表
很多情况下,网页中会使用列表显示数据,我们可以在tDataHelper类中封装一些方法,用于将DataTable对象中的数据转换为包含链接的HTML列表内容,如下面的代码。
C# |
public static string GetListHtml(DataTable data,string clientId,
string pkName,string textFieldName,string hrefTemplate,string target)
{
if (data == null || data.Rows.Count <= 0) return "";
if (data.Columns.Contains(pkName) == false) return "";
StringBuilder sb = new StringBuilder(1500);
sb.AppendFormat("<ul id='{0}' class='res_list'>", clientId);
for (int i = 0; i < data.Rows.Count; i++)
{
sb.AppendFormat("<li rownum='{0}'><a href='{1}' target='{2}'>{3}</a></li>",
i+1,
string.Format(hrefTemplate,data.Rows[i][pkName]),
target,
data.Rows[i][textFieldName]);
}
sb.Append("</ul>");
return sb.ToString();
}
|
代码中,GetListHtml()方法定义的参数包括:
- data,使用DataTable对象指定数据源。
- clientId,列表元素的id属性名。
- pkName,DataTable对象中主键字段的名称。
- textFieldName,在列表项(li元素)中显示的文本内容字段。
- hrefTemplate,列表项中a元素的href属性值模板,其中的{0}会使用每行的主键数据替换。
- target,a元素的target属性,如_blank、_self。
下面的代码演示了tDataHelper.GetListHtml()方法的应用。
C# |
using System;
using System.Data;
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DataTable data =
tApp.Db.GetJet().GetTable("select * from user_main");
tWeb.Write(tDataHelper.GetListHtml(data,"lst1","username","username",
"Edit.aspx?user={0}","_blank"));
}
}
|
代码中,会将user_main表中数据生成为操作列表,以username字段作为主键和显示内容;链接页面为Edit.aspx,并使用user参数指定用户名,生成的HTML内容如下。
HTML |
<ul id='lst1' class='res_list'>
<li rownum='1'><a href='Edit.aspx?user=user01' target='_blank'>user01</a></li>
<li rownum='2'><a href='Edit.aspx?user=user02' target='_blank'>user02</a></li>
<li rownum='3'><a href='Edit.aspx?user=user03' target='_blank'>user03</a></li>
<li rownum='4'><a href='Edit.aspx?user=user04' target='_blank'>user04</a></li>
<li rownum='5'><a href='Edit.aspx?user=user05' target='_blank'>user05</a></li>
</ul>
|
这里,在li元素中还添加了rownum属性用于指行列表项的行号,可以配合listview.js中的代码实现分页浏览功能,后续内容中会有详细讨论。