柚子Nan--回归原点

Everything can be as easy as you like or as complex as you need.
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[翻译]在DataTable中进行自由的计算

Posted on 2004-05-13 21:52  柚子Nan  阅读(3144)  评论(2编辑  收藏  举报

http://aspnet.4guysfromrolla.com/articles/082003-1.aspx
作者:Scott Mitchell

简介
我在阅读weblogs.asp.net上的blog的时候,发现Darren Neimke对于在一个DataTable中计算有用的数据很感兴趣,而且也很有见地。
在他的blog上,Darren 提到了DataTable两个重要的但并不被大家熟悉的特征:DataCloumn类的Expression属性和DataTable得Compute()方法。

在这个文章里,我们将简要的看看DataTable,DataCloumn类的Expression属性和DataTable得Compute()方法。接着,我们将用几个简短的例子说明如何使用这些属性和方法。

DataTable概览
DataTable类可以在System.Data命名空间里找到,对于每个DataTable在内存中增加一个映射表。如果你以前使用过DataSet,你肯定用过DataTable,因为一个DataSet是很多个DataTable的集合。

花点时间考虑一下DataTable的组成:由预先定义的列和不定数量的纪录行。所以,一点也不奇怪,DataTable有一个Columns属性,他就是一组DataColumns对象的集合。这些DataColumns对象确定了DataTable所有列的名称和类型。另外,DataTable有一个Rows属性,他是DataRow对象的集合。每一个DataRow对象对每个DataTable的列都有一个对应值。

DataTables可以通过静态的创建,即预先定义的数据、硬编码数据或者从数据库的查询产生。通常情况下,在建立Web程序原型或者测试一些功能的时候,使用静态数据创建DataTable并显示数据已经满足了需求。要完成这些,你需要按照如下操作:
1、创建一个DataTable对象。
2、创建一些DataColumn对象,把他们加到DataTable对象的Columns集合中。
3、增加一些纪录行。

$原文中有简单的例子,在此不做翻译$

使用Expression属性来创建Computed Columns

在前一个例子中,我们看到了如何使用sp_Popularity存储过程和DataTable把数据显示在DataGrid中。这个存储过程返回了ASPFAQs.com网站上浏览FAQ的top 10,包括了每个FAQ的浏览数量。现在,想象一下我们还想在DataGrid中显示一列来显示一个月中的预访问量,而且可能我们决定这个数字比当前的数量多10%。

如果我们使用特定的SQL查询数据库,增加这样计算列将会是一个难题。就是说,如果使用sp_Popularity存储过程,我们将会使用这样的查询语句
SELECT TOP 10 FAQID, ViewCount, ...
FROM tblFAQs
ORDER BY ViewCount DESC
为了这个计算列,我们将会纯粹增加一个select 语句,就像这样:
SELECT TOP 10 FAQID, ViewCount, ..., FutureClicks = ViewCount * 1.1
FROM tblFAQs
ORDER BY ViewCount DESC

我们用了存储过程来解决这个问题,然而我们一定会遇到用自己的方式来解决问题。我们可以这样解决问题:在从数据库中检索到数据放到DataTable以后,增加一个计算列。语法非常简单,只是创建一个DataColumn对象,然后设置它的Expression属性为我们想要计算的表达式,在这个例子中就是ViewCount * 1.1。然后把这列增加到DataTable中。实质上,我们只需要在刚才例子中的SqlDataAdapter's Fill() 函数后边,在实际的数据绑定之前增加三行代码。

 myAdapter.Fill(dt)

    Dim dcFutureViews as New DataColumn("Future Views", GetType(Integer))
    dcFutureViews.Expression = "ViewCount * 1.1"
    dt.Columns.Add(dcFutureViews) 
     
    'Bind the DataTable to the DataGrid

可以在这里看演示程序
http://aspnet.4guysfromrolla.com/demos/DataTableExpression.aspx
关于Expression属性的更多信息请参考
http://msdn.microsoft.com/library/default.asp?url=/library/en-

us/cpref/html/frlrfsystemdatadatacolumnclassexpressiontopic.asp

http://www.msdnaa.net/content/?ID=1861

用Compute()方法计算数值
DataTable包含一个Compute()方法,他通过传一个特定的过滤参数在行上计算特定的功能。Compute()方法返回一个标量值—运算执行的结果,所以这个方法在产生统计数据或者基于用户输入的统计的时候很有用。
函数定义如下:
Function Compute(expression as String, filter as String) as Object
例如,在上边的在线演示程序中,我们使用下边的语句可以计算所有FAQ的浏览次数在某个特定时间后的总和
Dim count as Integer
count = Convert.ToInt32(dt.Compute("SUM(ViewCount)", "DateEntered >

someDate"))

Compute()方法非常美妙,因为他是在一组记录上执行某种过滤操作。因此,我们可以根据用户输入的查询做一些有趣的,而且有价值的统计。在 Darren's blog上, 他说明了如何使用Compute()方法来让用户在文本框中输入一个查询字符串和匹配的数量来进行相应的动作。

为了演示Compute()方法,现在让我们创建一个页面,展示最受欢迎的FAQ,而且还可以让用户看到在某个特定的日子创建的所有FAQ浏览次数的平均值。为了做这个,我们需要一个TextBox让用户输入日期,还要一个Button的Click事件。另外,当页面回传的时候,需要重新显示DataTable(除非你决定缓存这些数据),我们将为此创建一个简单的函数GetData(),他从sp_Popularity存储过程中读取数据到DataTable中。
代码如下:
<script language="VB" runat="server">
  ...
 
  Sub DisplayStats(sender as Object, e as EventArgs)
    'Compute the avg.
    Dim dt as DataTable = GetData()
   
    Dim avg as Single
    avg = Convert.ToSingle(dt.Compute("AVG(ViewCount)", _
                 "DateEntered > '" & FAQDate.Text & "'"))
   
    Results.Text = "Average Views: " & avg
  End Sub

</script>

<form runat="server">
  Compute the average number of views for FAQs after a specified date:
  <asp:TextBox runat="server" id="FAQDate" />
  <asp:Button Text="Compute" runat="server" OnClick="DisplayStats" />
  <br />
  <asp:Label id="Results" runat="server" />
</form>

<p>
<asp:DataGrid runat="server" id="dgPeople"
 HeaderStyle-BackColor="LightGray"
 HeaderStyle-Font-Bold="True" />

结论:
在这个文章中,我们验证了DataGrid两个简单的功能:Compute()方法和Expression属性。另外,我们还看到了如何在实际环境中使用他们。

最后,祝
大家编程快乐!

Scott Mitchell
http://www.4guysfromrolla.com/ScottMitchell.shtml