Kevin Cheng's Yard

电脑是我的老婆,编程是我的灵魂,代码是我的语言,按键是我在歌唱。
精于斯,乐于斯。
 
 

与我联系

  • 发短消息

搜索

 

常用链接

  • 我的随笔
  • 我的空间
  • 我的短信
  • 我的评论
  • 更多链接
  • 我的参与
  • 我的新闻
  • 最新评论
  • 我的标签

留言簿

  • 给我留言
  • 查看留言

我参与的团队

  • .Net 商业智能(0/0)
  • .NetFramework3.0 & 3.5(WCF,WPF,WF)团队(0/0)

随笔分类

  • 日子(3) (rss)
  • .NET编程语言 (rss)
  • .NET杂项 (5) (rss)
  • .NET组件控件(8) (rss)
  • IT新闻(1) (rss)
  • 报表开发(1) (rss)
  • 代码生成器(1) (rss)
  • 工作流引擎 (rss)
  • 建模与快速开发 (5) (rss)
  • 门户框架Portal (rss)
  • 数据库 (4) (rss)
  • 用户界面方案 (rss)
  • 杂项(2) (rss)

随笔档案

  • 2009年5月 (2)
  • 2008年12月 (1)
  • 2008年8月 (1)
  • 2008年7月 (1)
  • 2007年12月 (1)
  • 2007年6月 (1)
  • 2007年5月 (1)
  • 2007年3月 (2)
  • 2007年1月 (1)
  • 2006年12月 (1)
  • 2006年11月 (1)
  • 2006年10月 (1)
  • 2006年9月 (1)
  • 2006年8月 (3)
  • 2006年6月 (5)
  • 2006年3月 (2)
  • 2005年12月 (7)

文章分类

  • .NET(1) (rss)

相册

  • 回忆

收藏夹

  • 弓虽贝占 (rss)

Blogs

  • DbToCode
  • RapidTier
  • SmartPersistenceLayer
  • 灵感之源

NET WebSite

  • ASP.NET
  • CodeProject
  • CSDN
  • GoDotNet
  • MSDN
  • SourceForge

Special

  • icsharpcode.com
  • Open License
  • Python

最新评论

  • 1. Re:Infragistics netadvantage UltraGrid (UltraWinGrid) 编程手记
  • 我现在有个小问题 在单击表头排序时.会有一个小箭头. 我在代码中.重新bind后.那个小箭头还会存在. 请问.有什么办法可以关闭它.让它重新按默认值排序?
  • --彦斌
  • 2. re: 爱上语法高亮控件ICSharpCode.TextEditor ~o~
  • 如何根据代码字符串获取所在行? 能否控制第几行到第几行可编辑,其余不可编辑呢? 望给解答! 我的邮箱CHUANGXIAOCHUN@YAHOO.COM.CN 谢谢...
  • --asato
  • 3. re: Infragistics netadvantage UltraGrid (UltraWinGrid) 编程手记
  • 你知道怎樣可以把一行 (Row) 向上移嘛!
  • --Joel WU
  • 4. re: 报表设计技巧-交叉报表模板
  • 楼主跟我用过的方法一样哈~~
  • --侯唯
  • 5. re: 报表设计技巧-交叉报表模板
  • ...建议先理解交叉报表的概念,就知道它最适合做这种事了。
    后台行列转换是相当无趣的事情,既耗精力又徒添加维护工作量,为什么不直接交给交叉报表来做呢?
  • --Kevin Cheng

阅读排行榜

  • 1. Infragistics netadvantage UltraGrid (UltraWinGrid) 编程手记(7028)
  • 2. 用 System.Xml 读写XML 整理文档(5401)
  • 3. ASP.NET AJAX Control Tookit 使用文档(5387)
  • 4. XML序列化与反序列化 整理文档(4585)
  • 5. 将ASP.NET用户控件转化为自定义控件(4459)

评论排行榜

  • 1. Gentle.NET 使用文档(26)
  • 2. Infragistics netadvantage UltraGrid (UltraWinGrid) 编程手记(24)
  • 3. 发布WebFtp 控件(ASP.NET控件,用以web方式进行文件上下传操作) (22)
  • 4. 爱上语法高亮控件ICSharpCode.TextEditor ~o~(18)
  • 5. 发布一个小工具(XNotePad),可以分页浏览很大的文本文件,速度理想(15)

Powered by: 博客园
模板提供:沪江博客
博客园 | 首页 | 发新随笔 | 发新文章 | 联系 | 订阅订阅 | 管理

2009年5月18日

报表设计技巧-交叉报表模板

传统的报表开发文章核心都是在介绍如何设置报表格式,标题、字段、如何获取数据什么的。这只是报表设计的入门而已,此文不在此论述。此文只论述批量设计报表的技巧 - 交叉报表模板。
传统思想看来,开发每张报表时都需要设计一张报表文件,这似乎是合情合理的。但在实际开发中,这种做法是极端耗费精力的(此后省略500字),反正我是不愿意这么做。
这个方法也是同事教我的,可采用交叉报表来简化报表设计步骤,在此借花献佛吧:

以crystal report为例(java的可试试jasper)
(1)预先定义水晶报表交叉报表模板。如:
    cross_1x1.rpt
    cross_2x1.rpt
    cross_3x1.rpt
    cross_2x2.rpt
    ....
(2)这些报表模板的字段名写死,如:
    column1
    column2
    column3
    column4
    column5
    ...
    value
(3)采用推模式为报表提供数据
    用代码获取数据(注意字段和报表模板的字段一致),再将数据推给水晶报表展示
    (个人认为拉模式是相当鸡肋的,这种方法将数据获取的步骤写死在报表文件里面,在实际应用中相当的不灵活)

效果:
(1)如以下数据:
    column1      column2     value
    瑞安         电话        1000
    瑞安         宽带        2000
    温州         电话        3000
    温州         宽带        4000
    ...
(2)使用交叉报表模板 cross_1x1.rpt 展示效果为:
              电话       宽带     合计
    瑞安      1000       2000     3000
    温州      3000       4000     7000
    合计      4000       6000     10000


故,报表开发人员的工作可简化为:
(1)设置报表条件:这个步骤也可以用配置文件自动生成
(2)获取报表数据:根据传递用户设置的条件获取数据
(3)指定报表模板
这样,开发人员工作重心就可以移到获取数据上面,无需和UI打交道,可大大提高了报表设计的工作效率,这在实际工作中是相当便利的。

 

posted @ 2009-05-18 10:00 Kevin Cheng 阅读(2087) | 评论 (10) | 编辑
 

2009年5月13日

发布一个小工具(XNotePad),可以分页浏览很大的文本文件,速度理想

发布一个小工具(XNotePad),可以分页浏览很大的文本文件,速度理想。

附加功能:(1)切割文本文件(2)语法着色

编这个小玩意的初衷是将小说切割了放到手机上看,用得着的话就拿去用吧。

点此下载

posted @ 2009-05-13 18:41 Kevin Cheng 阅读(2176) | 评论 (15) | 编辑
 

2008年12月12日

限制并发线程数例程(C#)

按自己的想法实现的C#版本的限制并发线程数的例程,给有需要的读者

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace WZDM.Test
{
    /// <summary>
    /// 限制并发线程数例程
    /// </summary>
    public class TestThread 
    {
        int _currentThreads = 0;
        int _maxThreads = 10;

        public void Test()
        {
            while (true)
            {
                //_maxThreads = new Random().Next(1, 10);
                for (int i=0; i<100; i++)
                {
                    // 在此进行数量限制
                    if (_currentThreads >= _maxThreads)
                        break;

                    // 开启线程
                    lock (typeof(TestThread))
                    {
                        _currentThreads++;
                        if (_currentThreads > _maxThreads)
                            _currentThreads = _maxThreads;

                        string currentInfo = string.Format("thread {0}/{1}", _currentThreads, _maxThreads);
                        Console.WriteLine(currentInfo + " start");
                        Thread thread = new Thread(new ParameterizedThreadStart(Run));
                        thread.Start(currentInfo);
                    }
                }

                System.Threading.Thread.Sleep(2000);
            }
        }

        // 线程任务
        void Run(object obj)
        {
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine("{0}:{1}", obj, i);
                Thread.Sleep(100);
            }
            Console.WriteLine("{0} finished", obj);


            lock (typeof(TestThread))
            {
                _currentThreads--;
                if (_currentThreads < 0)
                    _currentThreads = 0;
            }
        }
    }
}

posted @ 2008-12-12 09:45 Kevin Cheng 阅读(304) | 评论 (0) | 编辑
 

2008年8月20日

Infragistics netadvantage UltraGrid (UltraWinGrid) 编程手记
     摘要: UltraGrid 是Infragistics netadvanage 控件库中提供的一个Windows 网格控件,功能强大,完全可以取代VS 中提供的 GridView控件。但不知为何,国内介绍它的文章很少。这玩意功能是相当强大,但其属性设计原理和普通控件不太一样,属性极为复杂,没有手册几乎无法编码。在此我整理了一些资料,权当推广了。本是编程用的参考,文笔随意之处望见谅。kevin cheng ... 阅读全文
posted @ 2008-08-20 12:03 Kevin Cheng 阅读(7028) | 评论 (24) | 编辑
 

2008年7月31日

将 DataTable 转化为 Excel Xml 格式供下载

做网站项目时,常需要将表格转化为 Excel 文件供用户下载,实现方法有很多种。如:

    (1)将DataTable 直接进行 xml 序列化成文本

    (2)将DataTable 转化为 Html table 格式

    (3)将DataTable 转化为 Excel Xml 格式

    (4)使用 Microsoft.Office.Interop.Excel.dll 创建Excel文件,再依次填写单元格数据

 

测试了这些方法,发现第3种简单且稳定,其它几种方法都有这样那样的小麻烦(如乱码和文件权限问题),我不在此一一提供这些方法的实现代码。以下为第3种方法的代码,本文参考了该篇文章:http://www.cnblogs.com/tsoukw/archive/2008/05/30/1210485.html,在此,我用静态函数实现了该功能。希望对大家有用。

 

excel xml 格式如:

 

Code
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook
 xmlns
="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:ss
="urn:schemas-microsoft-com:office:spreadsheet">
 
<Worksheet ss:Name="Sheet1">
  
<Table>
   
<Row>
     
<Cell ss:MergeAcross="1"><Data ss:Type="String">Excel xml</Data></Cell>
   
</Row>
   
<Row>
    
<Cell><Data ss:Type="String">A2</Data></Cell>
    
<Cell><Data ss:Type="Number">0.112</Data></Cell>
   
</Row>
  
</Table>
 
</Worksheet>
</Workbook>

 

以下是生成 excel xml 的源代码:

 

Code
        // datatable -> excel
        public static void ExportExcel(DataTable dt, string fileName, string[] displayColumnNames, string[] displayColumnCaptions)
        {
            Response.ClearContent();
            Response.ContentEncoding 
= System.Text.Encoding.UTF8;
            Response.ContentType 
= "application/vnd.ms-excel; charset=utf-8";
            Response.AddHeader(
"Content-Disposition", "attachment;filename=" + fileName);
            Response.Write(DataTableToExcelTable(dt, displayColumnNames, displayColumnCaptions));
            Response.End();
        }

        
// 将 DataTable 转化为 ExcelXml
        public static string DataTableToExcelTable(DataTable dt, string[] displayColumnNames, string[] displayColumnCaptions)
        {
            
// 表开始
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(
"<?xml version=\"1.0\"?>");
            sb.AppendLine(
"<?mso-application progid=\"Excel.Sheet\"?>");
            sb.AppendLine(
"<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\">");
            sb.AppendLine(
" <Worksheet ss:Name=\"Sheet1\">");
            sb.AppendLine(
"  <Table>");

            
//
            
// 输出标题
            
//
            sb.AppendLine("   <Row>");
            
if (displayColumnCaptions != null)
            {
                
// 输出指定列标题
                for (int i = 0; i < displayColumnCaptions.Length; i++)
                    sb.AppendLine(
"    <Cell><Data ss:Type=\"String\">" + displayColumnCaptions[i] + "</Data></Cell>");
            }
            
else if (displayColumnNames != null)
            {
                
// 输出展示列标题
                for (int i = 0; i < displayColumnNames.Length; i++)
                    sb.AppendLine(
"    <Cell><Data ss:Type=\"String\">" + displayColumnNames[i] + "</Data></Cell>");
            }
            
else
            {
                
// 输出所有列标题
                for (int i = 0; i < dt.Columns.Count; i++)
                    sb.AppendLine(
"    <Cell><Data ss:Type=\"String\">" + dt.Columns[i].Caption + "</Data></Cell>");
            }
            sb.AppendLine(
"   </Row>");

            
//
            
// 输出数据
            
//
            if (displayColumnNames != null)
            {
                
// 输出指定列数据
                foreach (DataRow dr in dt.Rows)
                {
                    sb.AppendLine(
"   <Row>");
                    
foreach (string colName in displayColumnNames)
                        sb.AppendLine(
"    <Cell><Data ss:Type=\"String\">" + dr[colName].ToString() + "</Data></Cell>");
                    sb.AppendLine(
"   </Row>");
                }
            }
            
else
            {
                
//输出所有列数据
                foreach (DataRow dr in dt.Rows)
                {
                    sb.AppendLine(
"   <Row>");
                    Object[] ary 
= dr.ItemArray;
                    
for (int i = 0; i <= ary.GetUpperBound(0); i++)
                        sb.AppendLine(
"    <Cell><Data ss:Type=\"String\">" + ary[i].ToString() + "</Data></Cell>");
                    sb.AppendLine(
"   </Row>");
                }
            }

            
// 表结束
            sb.AppendLine("  </Table>");
            sb.AppendLine(
" </Worksheet>");
            sb.AppendLine(
"</Workbook>");
            
return sb.ToString();
        }

 

此外需注意,必须导出为 UTF-8格式的xml,否则excel 无法打开该文件,会报错滴~

posted @ 2008-07-31 15:54 Kevin Cheng 阅读(546) | 评论 (0) | 编辑
 

2007年12月10日

隐藏ASP.NET 2.0 Wizard控件的完成按钮

kevin cheng 2007-12-10
这冬冬烦了我一下午,以下是解决思路:
(1)Wizard并没有提供直接访问导航按钮的方式,必须自己用FindControl来找到它
(2)使用FindControl找到的导航按钮并不能直接用Visible=false来隐藏(可能和wizard部件的生成顺序有关)
(3)可使用control.Parent.Remove(control)的方法移除之,如:

// 隐藏完成按钮
void HideFinishButton(Wizard wizard)
{
    Button btn 
= wizard.FindControl("FinishNavigationTemplateContainerID").FindControl("FinishButton") as Button;
    btn.Parent.Controls.Remove(btn);
    
//btn.Visible = false;  // 此句无任何效果!
}
posted @ 2007-12-10 23:00 Kevin Cheng 阅读(429) | 评论 (0) | 编辑
 

2007年6月18日

整理的 AjaxControlToolkit.chm ,希望对大家有用
下载:AjaxControlToolkit.rar
posted @ 2007-06-18 15:33 Kevin Cheng 阅读(1600) | 评论 (10) | 编辑
 

2007年5月29日

发布AccessConsole(Access 控制台工具)

Kevin Cheng 2007-05

这玩意是用来操作access数据库的,尽量模仿oracle的sqlplus,没什么好介绍的了(可用help命令或者-h参数查看帮助),自己用着玩吧。希望对大家有帮助。
Download

posted @ 2007-05-29 13:05 Kevin Cheng 阅读(605) | 评论 (4) | 编辑
 

2007年3月13日

用 System.Xml 读写XML 整理文档

example
    <?xml version="1.0" encoding="utf-8"?>
    <LinkLibrary xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="bb" Url="aa" Desc="aa" />
      <Link Cat="cc" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
    </LinkLibrary>


XML概念
    Root        XML根节点,只能且必须有一个(以上为LinkLibrary)
    Element     节点元素(如Link)
    Attribute   节点属性(如Cat, Url, Desc)
    Content     内容(非空白文本、CDATA、Element、EndElement、EntityReference 或 EndEntity)节点

 

System.Xml空间
    以下类适合快速流式读写XML文件(注:DOM适合随机读写)
    XmlReader, XmlWriter,
    XmlTextReader, XmlTextWriter
    XmlValidatingReader, XmlValidatingWriter    添加了DTD和模式验证,因此提供了数据的有效性验证
    XmlNodeReader, XmlNodeWriter                把XmlNode作为其源


节点类型(public enum XmlNodeType)
     XmlDeclaration        XML 声明(例如,<?xml version='1.0'?>)。
     Attribute             属性(例如,id='123')。
     CDATA                 CDATA 节(例如,<![CDATA[my escaped text]]>)。
     Comment               注释(例如,<!-- my comment -->)
     Document              作为文档树的根的文档对象提供对整个 XML 文档的访问。
     DocumentFragment      文档片段。
     DocumentType          由以下标记指示的文档类型声明(例如,<!DOCTYPE...>)。
     Element               元素(例如,<item>)。
     EndElement            末尾元素标记(例如,</item>)。
     Entity                实体声明(例如,<!ENTITY...>)。
     EndEntity             由于调用 ResolveEntity 而使 XmlReader 到达实体替换的末尾时返回。 
     EntityReference       实体引用(例如,&num;)。
     None                  如果未调用 Read 方法,则由 XmlReader 返回。 
     Notation              文档类型声明中的表示法(例如,<!NOTATION...>)。
     ProcessingInstruction 处理指令(例如,<?pi test?>)。
     SignificantWhitespace 混合内容模型中标记间的空白或 xml:space="preserve" 范围内的空白。 
     Text                  节点的文本内容。
     Whitespace            标记间的空白。 
    


------------------------------------------------------------------------
使用XmlTextReader快速读取
------------------------------------------------------------------------
创建
    打开            XmlTextReader reader = new XmlTextReader("*.xml");
    关闭            reader.Close();

属性
    常用
        HasAttributes            获取一个值,该值指示当前节点是否有任何属性。(从 XmlReader 继承。)
        HasValue                 获取一个值,该值指示当前节点是否可以具有非 String.Empty 的 Value。
        AttributeCount           获取当前节点上的属性数。
        Value                    获取当前节点的文本值。
        ValueType                获取当前节点的公共语言运行库 (CLR) 类型。(从 XmlReader 继承。)
        Name                     获取当前节点的限定名。
    其它
        BaseURI                  获取当前节点的基 URI。
        CanReadBinaryContent     获取一个值,该值指示 XmlTextReader 是否实现二进制内容读取方法。
        CanReadValueChunk        获取一个值,该值指示 XmlTextReader 是否实现 ReadValueChunk 方法。
        CanResolveEntity         获取一个值,该值指示此读取器是否可以分析和解析实体。
        Depth                    获取 XML 文档中当前节点的深度。
        Encoding                 获取文档的编码方式。
        EntityHandling           获取或设置一个值,该值指定读取器如何处理实体。
        EOF                      获取一个值,该值指示读取器是否定位在流的结尾。
        IsDefault                获取一个值,该值指示当前节点是否是从 DTD 或架构中定义的默认值生成的属性。
        IsEmptyElement           获取一个值,该值指示当前节点是否为空元素(例如,<MyElement/>)。
        Item                     当在派生类中被重写时,获取此属性的值。(从 XmlReader 继承。)
        LineNumber               获取当前行号。
        LinePosition             获取当前行位置。
        LocalName                获取当前节点的本地名称。
        Namespaces               获取或设置一个值,该值指示是否进行命名空间支持。
        NamespaceURI             获取读取器定位在的节点的命名空间 URI(采用 W3C 命名空间规范中定义的形式)。
        NameTable                获取与此实现关联的 XmlNameTable。
        NodeType                 获取当前节点的类型。
        Normalization            获取或设置一个值,该值指示是否正常化空白和属性值。
        Prefix                   获取与当前节点关联的命名空间前缀。
        ProhibitDtd              获取或设置一个值,该值指示是否允许 DTD 处理。
        QuoteChar                获取用于括起属性节点值的引号字符。
        ReadState                获取读取器的状态。
        SchemaInfo               获取作为架构验证结果分配给当前节点的架构信息。(从 XmlReader 继承。)
        Settings                 获取用于创建此 XmlTextReader 实例的 XmlReaderSettings 对象。
        WhitespaceHandling       获取或设置一个值,该值指定如何处理空白。
        XmlLang                  获取当前 xml:lang 范围。
        XmlResolver              设置用于解析 DTD 引用的 XmlResolver。
        XmlSpace                 获取当前 xml:space 范围。

方法
    定位           
        MoveToAttribute            移动到指定的属性。 
        MoveToContent              检查当前节点是否是内容节点, 如果此节点不是内容节点,则读取器向前跳至下一个内容节点或文件结尾。
        MoveToElement              移动到包含当前属性节点的元素
        MoveToFirstAttribute       移动到第一个属性
        MoveToNextAttribute      移动到下一个属性
        Skip                                跳过当前节点的子级。 
        IsStartElement                测试当前内容节点是否是开始标记。
 
    基本读取           
        Read                       读取一个节点
        ReadString                 将元素或文本节点的内容读取为一个字符串。


    读取特定类型
        ReadBase64                 对 Base64 进行解码并返回解码的二进制字节。
        ReadBinHex                 对 BinHex 进行解码并返回解码后的二进制字节
        ReadChars                  将元素的文本内容读入字符缓冲区。通过连续调用此方法,可以读取大的嵌入文本流。
        ReadValueChunk             读取嵌入在 XML 文档中的大量文本流。 (从 XmlReader 继承。)
        ReadInnerXml               将内部XML节点内容读到一个字符串中
        ReadOuterXml               所有XML节点内容(包括自身节点)

    读取节点
        ReadStartElement           检查当前节点是否为元素并将读取器推进到下一个节点。
        ReadElementString          这是一个用于读取简单纯文本元素的 Helper 方法。
        ReadAttributeValue         将属性值分析为一个或多个 Text、EntityReference 或 EndEntity 节点
        ReadEndElement             检查当前内容节点是否为结束标记并将读取器推进到下一个节点。
        GetAttribute                   获取属性的值。 

    读取内容并转化
        ReadContentAs...           将内容作为指定类型的对象读取。 (从 XmlReader 继承。)
        ReadElementContentAs...    读取当前元素,并将内容作为指定类型的对象返回。 (从 XmlReader 继承。)

    追溯读取
        ReadToFollowing            一直读取,直到找到具有指定限定名的元素
        ReadToDescendant           让 XmlReader 前进到下一个匹配的子代元素。
        ReadToNextSibling          让 XmlReader 前进到下一个匹配的同级元素。
        GetRemainder               获取已缓冲的 XML 剩余部分。
        ReadSubtree                返回新的 XmlReader 实例,此实例可用于读取当前节点及其所有子节点。
 

 

 

------------------------------------------------------------------------
使用XmlTextWriter快速写入
------------------------------------------------------------------------
开闭           
    XmlTextWriter writer = new XmlTextWriter(@"c:\mywriter.xml", null);
    writer.Close();
   
起止XML文档 (<?xml version="1.0"?>
    writer.WriteStartDocument();
    writer.EndDocument();

声明XML格式
    writer.Formatting  = Formatting.Indented;
    writer.Indentation = 缩进字符数
    writer.IndentChar  = 缩进字符
    writer.QuoteChar   = 单引号|双引号

输出注释 (<!-- comment text -->)
    writer.WriteComment("comment text");

输出元素 (<Element>ElementVal</Element>)
    writer.WriteElementString("Element", "ElementVal");
    或者
    writer.StartElement("Element");
    writer.WriteString("ElementVal");
    writer.EndElement();

输出元素属性 (<Element Property="PropertyVal">ElementVal</Element>)
    writer.StartElement("Element");
    writer.WriteAttributeString("Property", "PropertyVal");
    writer.WriteString("ElementVal");
    writer.EndElement();

输出CDATA (<!CDATA>....</CDATA>
    WriteCData("....")

输出字符缓冲区文本
    WriteChars(char[], startPos, length)
   
   

------------------------------------------------------------------------
读例程
------------------------------------------------------------------------
XML文件
    <!-- sample xml file -->
    <bookstore>
      <book genre='novel' ISBN='10-861003-324'>
        <title>The Handmaid's Tale</title>
        <price>19.95</price>
      </book>
      <book genre='novel' ISBN='1-861001-57-5'>
        <title>Pride And Prejudice</title>
        <price>24.95</price>
      </book>
    </bookstore>


取每个书节点上的ISBN属性
    using (XmlReader reader = XmlReader.Create("books.xml"))
    {
        reader.ReadToFollowing("book");
        do {
           Console.WriteLine("ISBN: {0}", reader.GetAttribute("ISBN"));
        } while (reader.ReadToNextSibling("book"));
    }

跳到子节点
    using (XmlReader reader = XmlReader.Create("2books.xml"))
    {
        reader.MoveToContent();                 // bookstore
        reader.ReadToDescendant("book");        // 第一个book
        reader.Skip(); //Skip the first book.   // 第二个book
        ...
    }
   
挖到子节点
    using (XmlReader reader = XmlReader.Create("book3.xml"))
    {
        reader.Read();
        reader.ReadStartElement("book");
            reader.ReadStartElement("title");
                Console.WriteLine("The content of the title element:  {0}", reader.ReadString());
            reader.ReadEndElement();
            reader.ReadStartElement("price");
                Console.WriteLine("The content of the price element:  {0}", reader.ReadString());
            reader.ReadEndElement();
        reader.ReadEndElement();
    }

 

读到指定位置  
   FileStream fs = new FileStream("..\\..\\..\\books.xml", FileMode.Open);
   XmlTextReader tr = new XmlTextReader(fs);
   while(!tr.EOF)
   {
      // 查找类型为XmlNodeType.Element和名称为title的节点
      if(tr.MoveToContent() == XmlNodeType.Element && tr.Name=="title")
      {
         listBox1.Items.Add(tr.ReadElementString());
      }
      else
      {
         tr.Read();
      }
    }

遍历元素属性
   string fileName = "..\\..\\..\\books.xml";
   XmlTextReader tr = new XmlTextReader(fileName);
   while(tr.Read())
   {
      //check to see if it's a NodeType element
      if(tr.NodeType == XmlNodeType.Element) 
      {
         //if it's an element, then let's look at the attributes.
         for(int i = 0; i < tr.AttributeCount; i++) {
            listBox1.Items.Add(tr.GetAttribute(i));
      }
}

   
------------------------------------------------------------------------
写例程
------------------------------------------------------------------------
     XmlTextWriter writer = new XmlTextWriter (filename, null);

     //Use indenting for readability.
     writer.Formatting = Formatting.Indented;

     //xml声明(Write the XML delcaration. )
     writer.WriteStartDocument();

     //预处理指示(Write the ProcessingInstruction node.)
     String PItext="type='text/xsl' href='book.xsl'";
     writer.WriteProcessingInstruction("xml-stylesheet", PItext);

     //文档类型(Write the DocumentType node.)
     writer.WriteDocType("book", null , null, "<!ENTITY h 'hardcover'>");
       
     //注释(Write a Comment node.)
     writer.WriteComment("sample XML");
   
     //根元素(Write a root element.)
     writer.WriteStartElement("book");

     //属性值(Write the genre attribute.)
     writer.WriteAttributeString("genre", "novel");
   
     //属性值(Write the ISBN attribute.)
     writer.WriteAttributeString("ISBN", "1-8630-014");

     //Write the title.
     writer.WriteElementString("title", "The Handmaid's Tale");
             
     //Write the style element.
     writer.WriteStartElement("style");
     writer.WriteEntityRef("h");
     writer.WriteEndElement();

     //文本元素节点(Write the price.)
     writer.WriteElementString("price", "19.95");

     //[CDATA]
     writer.WriteCData("Prices 15% off!!");

     //Write the close tag for the root element.
     writer.WriteEndElement();
            
     writer.WriteEndDocument();

     //Write the XML to file and close the writer.
     writer.Flush();
     writer.Close(); 

     //Load the file into an XmlDocument to ensure well formed XML.
     XmlDocument doc = new XmlDocument();
     //Preserve white space for readability.
     doc.PreserveWhitespace = true;
     //Load the file.
     doc.Load(filename); 
   
     //Display the XML content to the console.
     Console.Write(doc.InnerXml); 


------------------------------------------------------------------------
带验证的读写
------------------------------------------------------------------------
    books.xml
        <?xml version='1.0'?>
        <!-- This file represents a fragment of a book store inventory database -->
        <bookstore xmlns="x-schema:books.xdr">
           <book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0">
              <title>The Autobiography of Benjamin Franklin</title>
              <author>
                 <first-name>Benjamin</first-name>
                 <list-name>Franklin</last-name>
              </author>
              <price>8.99</price>
           </book>
           ...
        </bookstore>
    books.xdr
        <?xml version="1.0"?>
        <Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">
           <ElementType FTEL="first-name" content="textOnly"/>
           <ElementType FTEL="last-name" content="textOnly"/>
           <ElementType FTEL="name" content="textOnly"/>
           <ElementType FTEL="price" content="textOnly" dt:type="fixed.14.4"/>
           <ElementType FTEL="author" content="eltOnly" order="one">
              <group order="seq">
                 <element type="name"/>
              </group>
              <group order="seq">
                 <element type="first-name"/>
                 <element type="last-name"/>
              </group>
           </ElementType>
           <ElementType FTEL="title" content="textOnly"/>
           <AttributeType FTEL="genre" dt:type="string"/>
           <ElementType FTEL="book" content="eltOnly">
              <attribute type="genre" required="yes"/>
              <element type="title"/>
              <element type="author"/>
              <element type="price"/>
           </ElementType>
           <ElementType FTEL="bookstore" content="eltOnly">
              <element type="book"/>
           </ElementType>
        </Schema>
    cs
        using System.Xml.Schema;
        protected void button1_Click (object sender, System.EventArgs e)
        {
           //change this to match your path structure.
           string fileName = "..\\..\\..\\booksVal.xml";
           XmlTextReader tr = new XmlTextReader(fileName);
           XmlValidatingReader trv = new XmlValidatingReader(tr);
        
           //Set validation type
           trv.ValidationType=ValidationType.XDR;
           //Add in the Validation eventhandler
           trv.ValidationEventHandler += new ValidationEventHandler(this.ValidationEvent);
        
           //Read in node at a time       
           while(trv.Read()) 
           {
              if(trv.NodeType == XmlNodeType.Text)
              listBox1.Items.Add(trv.Value);
           }
        }
        public void ValidationEvent (object sender, ValidationEventArgs args)
        {
           MessageBox.Show(args.Message);
        }

posted @ 2007-03-13 22:01 Kevin Cheng 阅读(5401) | 评论 (8) | 编辑
 
XML序列化与反序列化 整理文档

XML序列化与反序列化
    // OBJECT -> XML
    public static void SaveXml(string filePath, object obj) { SaveXml(filePath, obj, obj.GetType()); }
    public static void SaveXml(string filePath, object obj, System.Type type)
    {
        using (System.IO.StreamWriter writer = new System.IO.StreamWriter(filePath))
        {
            System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(type);
            xs.Serialize(writer, obj);
            writer.Close();
        }
    }
    // XML -> OBJECT
    public static object LoadXml(string filePath, System.Type type)
    {
        if (!System.IO.File.Exists(filePath))
            return null;
        using (System.IO.StreamReader reader = new System.IO.StreamReader(filePath))
        {
            System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(type);
            object obj = xs.Deserialize(reader);
            reader.Close();
            return obj;
        }
    }

相关的常用Attribute(命名空间System.Xml.Serialization )
    [XmlRootAttribute("PurchaseOrder", Namespace="http://www.cpandl.com", IsNullable=false)]  // 指定根
    [XmlIgnoreAttribute]                                                                      // 跳过不序列化
    [XmlArrayAttribute("Items")] public OrderedItem[] OrderedItems;                           // 层次序列化: <Items><OrderedItem.../><OrderedItem.../>..</Items>
    [XmlElementAttribute(ElementName="Link", IsNullable=false)] public Link[] Links;          // 平面序列化: <Link ..../><Link .../>...
    [XmlAttribute("Cat")] public string Cat;                                                  // 表现为属性<... Cat=.. />
    [XmlElementAttribute(IsNullable=false)]                                                   // 表现为节点<Cat>..</cat>


相关的全部Attribute(命名空间System.Xml.Serialization )
    XmlAttributes                     表示一个特性对象的集合,这些对象控制 XmlSerializer 如何序列化和反序列化对象。
    XmlArrayAttribute                 指定 XmlSerializer 应将特定的类成员序列化为 XML 元素数组。
    XmlArrayItemAttribute             指定 XmlSerializer 可以放置在序列化数组中的派生类型。
    XmlArrayItemAttributes            表示 XmlArrayItemAttribute 对象的集合。
    XmlAttributeAttribute             指定 XmlSerializer 应将类成员作为 XML 特性序列化。
    XmlChoiceIdentifierAttribute      指定可以通过使用枚举来进一步消除成员的歧义。
    XmlElementAttribute               在 XmlSerializer 序列化或反序列化包含对象时,指示公共字段或属性表示 XML 元素。
    XmlElementAttributes              表示 XmlElementAttribute 的集合,XmlSerializer 将其用于它重写序列化类的默认方式。
    XmlEnumAttribute                  控制 XmlSerializer 如何序列化枚举成员。
    XmlIgnoreAttribute                指示 XmlSerializer 的 Serialize 方法不序列化公共字段或公共读/写属性值。
    XmlIncludeAttribute               允许 XmlSerializer 在它序列化或反序列化对象时识别类型。
    XmlRootAttribute                  控制视为 XML 根元素的属性目标的 XML 序列化。
    XmlTextAttribute                  当序列化或反序列化包含类时,向 XmlSerializer 指示应将此成员作为 XML 文本处理。
    XmlTypeAttribute                  控制当属性目标由 XmlSerializer 序列化时生成的 XML 架构。
    XmlAnyAttributeAttribute          指定成员(返回 XmlAttribute 对象的数组的字段)可以包含任何 XML 属性。
    XmlAnyElementAttribute            指定成员(返回 XmlElement 或 XmlNode 对象的数组的字段)可以包含对象,该对象表示在序列化或反序列化的对象中没有相应成员的所有 XML 元素。
    XmlAnyElementAttributes           表示 XmlAnyElementAttribute 对象的集合。
    XmlAttributeEventArgs             为 UnknownAttribute 事件提供数据。
    XmlAttributeOverrides             允许您在使用 XmlSerializer 序列化或反序列化对象时重写属性、字段和类特性。
    XmlElementEventArgs               为 UnknownElement 事件提供数据。
    XmlNamespaceDeclarationsAttribute 指定目标属性、参数、返回值或类成员包含与 XML 文档中所用命名空间关联的前缀。
    XmlNodeEventArgs                  为 UnknownNode 事件提供数据。
    XmlSerializer                     将对象序列化到 XML 文档中和从 XML 文档中反序列化对象。XmlSerializer 使您得以控制如何将对象编码到 XML 中。
    XmlSerializerNamespaces           包含 XmlSerializer 用于在 XML 文档实例中生成限定名的 XML 命名空间和前缀。
    XmlTypeMapping                    包含从一种类型到另一种类型的映射。


xml序列化答疑
    (1)需序列化的字段必须是公共的(public)
    (2)需要序列化的类都必须有一个无参的构造函数
    (3)枚举变量可序列化为字符串,无需用[XmlInclude]
    (4)导出非基本类型对象,都必须用[XmlInclude]事先声明。该规则递归作用到子元素
        如导出ArrayList对象,若其成员是自定义的,需预包含处理:
        using System.Xml.Serialization;
        [XmlInclude(typeof(自定义类))]
    (5)Attribute中的IsNullable参数若等于false,表示若元素为null则不显示该元素。
        也就是说:针对值类型(如结构体)该功能是实效的
        若数组包含了100个空间,填充了10个类对象,则序列化后只显示10个节点
        若数组包含了100个空间,填充了10个结构体对象,则序列化后会显示100个节点
    (6)真正无法XML序列化的情况
        某些类就是无法XML序列化的(即使使用了[XmlInclude])
            IDictionary(如HashTable)
            System.Drawing.Color
            System.Drawing.Font
            SecurityAttribute声明
        父类对象赋予子类对象值的情况
        对象间循环引用
    (7)对于无法XML序列化的对象,可考虑
        使用自定义xml序列化(实现IXmlSerializable接口)
        实现IDictionary的类,可考虑(1)用其它集合类替代;(2)用类封装之,并提供Add和this函数
        某些类型需要先经过转换,然后才能序列化为 XML。如XML序列化System.Drawing.Color,可先用ToArgb()将其转换为整数
        过于复杂的对象用xml序列化不便的话,可考虑用二进制序列化


------------------------------------------------------------------------------------
高级议题
------------------------------------------------------------------------------------
序列化中异常的扑捉
    使用Exception.Message只会得到简单的信息“行***错误"
    可以使用Exception.InnerException.Message得到更详尽的信息

可使用事件代理来处理解析不了的XML节点
    XmlSerializer serializer = new XmlSerializer(typeof(PurchaseOrder));
    serializer.UnknownNode+= new XmlNodeEventHandler(serializer_UnknownNode);
    serializer.UnknownAttribute+= new  XmlAttributeEventHandler(serializer_UnknownAttribute);
    protected void serializer_UnknownNode(object sender, XmlNodeEventArgs e)
    {
      Console.WriteLine("Unknown Node:" +   e.Name + "\t" + e.Text);
    }
    protected void serializer_UnknownAttribute(object sender, XmlAttributeEventArgs e)
    {
      System.Xml.XmlAttribute attr = e.Attr;
      Console.WriteLine("Unknown attribute " +  attr.Name + "='" + attr.Value + "'");
    }

集合类(IEnumerable, ICollection)必须满足下列规则才可XML序列化:
    - 不得实现 IDictionary。
    - 必须有一个 Add 方法,该方法不是由该接口定义的,因为它通常是为该集合将要容纳的专用类型而创建的
    - 必须有一个索引器, 且参数为 System.Int32 (C# int)
    - 在 Add、Count 和索引器中不能有任何安全特性(SecurityAttribute)
    可序列化集合类例程:
        public class PublisherCollection : CollectionBase
        {
          public int Add(Publisher value)
          {
            return base.InnerList.Add(value);
          }
          public Publisher this[int idx]
          {
            get { return (Publisher) base.InnerList[idx]; }
            set { base.InnerList[idx] = value; }
          }
        }


某些类是以程序集的形式提供的,无法修改其源码。可用XmlAttributeOverrides设置其序列化特性
     XML目标
        <?xml version="1.0" encoding="utf-8"?>
        <Inventory xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
           <Product>
              <ProductID>100</ProductID>
              <ProductName>Product Thing</ProductName>
              <SupplierID>10</SupplierID>
           </Product>
           <Book>
              <ProductID>101</ProductID>
              <ProductName>How to Use Your New Product Thing</ProductName>
              <SupplierID>10</SupplierID>
              <ISBN>123456789</ISBN>
           </Book>
        </Inventory>
    源类(无法修改)
        public class Inventory
        {
           private Product[] stuff;
           public Inventory() {}
           public Product[] InventoryItems {get {return stuff;} set {stuff=value;}}
        }
    附加XmlAttributeOverrides后即可序列化
       XmlAttributes attrs = new XmlAttributes();
       attrs.XmlElements.Add(new XmlElementAttribute("Book", typeof(BookProduct)));
       attrs.XmlElements.Add(new XmlElementAttribute("Product", typeof(Product)));
       //add to the Attributes collection
       XmlAttributeOverrides attrOver = new XmlAttributeOverrides();
       attrOver.Add(typeof(Inventory), "InventoryItems", attrs);
       //deserialize and load data into the listbox from deserialized object
       FileStream f=new FileStream("..\\..\\..\\inventory.xml",FileMode.Open);
       XmlSerializer newSr=new XmlSerializer(typeof(Inventory), attrOver);
       Inventory newInv = (Inventory)newSr.Deserialize(f);

 

 

------------------------------------------------------------------------------------
最简单的示例
-------------------------------------------------------------------------------------
类设计
    public class MyClass  {public MyObject MyObjectProperty;}
    public class MyObject {public string ObjectName;}

序列化的 XML:
    <MyClass>
        <MyObjectProperty>
            <Objectname>My String</ObjectName>
        </MyObjectProperty>
    </MyClass>


 
------------------------------------------------------------------------------------
示例: 序列化数组,并限制数组元素类型
-------------------------------------------------------------------------------------
类设计
    public class Things
    {
       [XmlElement(DataType = typeof(string)), XmlElement(DataType = typeof(int))]
       public object[] StringsAndInts;
    }

生成的 XML 可能为:
    <Things>
       <string>Hello</string>
       <int>999</int>
       <string>World</string>
    </Things>

 

-------------------------------------------------------------------------------------
示例: 序列化数组
-------------------------------------------------------------------------------------
类设计
    using System.Xml.Serialization;
    [XmlRootAttribute("LinkLibrary", IsNullable = false, Namespace="http://www.wztelecom.cn")]
    public class LinkLib
    {
        [XmlElementAttribute(ElementName="Link", IsNullable=false)]
        public Link[] Links;
        public LinkLib()
        {
            Links = new Link[50];
            Links[0] = new Link("aa", "aa", "aa");
            Links[1] = new Link("bb", "aa", "aa");
            Links[2] = new Link("cc", "aa", "aa");
            Links[3] = new Link("aa", "aa", "aa");
            Links[4] = new Link("aa", "aa", "aa");
            Links[5] = new Link("aa", "aa", "aa");
            Links[6] = new Link("aa", "aa", "aa");
            Links[7] = new Link("aa", "aa", "aa");
            Links[8] = new Link("aa", "aa", "aa");
            Links[9] = new Link("aa", "aa", "aa");
        }
    }
    public class Link
    {
        [XmlAttribute("Cat")] public string Cat;
        [XmlAttribute("Url")] public string Url;
        [XmlAttribute("Desc")]public string Desc;
        public Link(){}
        public Link(string cat, string url, string desc)
        {
            Cat = cat;
            Url = url;
            Desc = desc;
        }
    }

目标XML文件
    <?xml version="1.0" encoding="utf-8"?>
    <LinkLibrary xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="bb" Url="aa" Desc="aa" />
      <Link Cat="cc" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
      <Link Cat="aa" Url="aa" Desc="aa" />
    </LinkLibrary>

若使用[XmlArrayAttribute("Links")] public Link[] Links;则序列化后的xml文件会多出一层:
    <?xml version="1.0" encoding="utf-8"?>
    <LinkLibrary xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
         <Links>
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="bb" Url="aa" Desc="aa" />
              <Link Cat="cc" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
              <Link Cat="aa" Url="aa" Desc="aa" />
         </Links>
    </LinkLibrary>

 

-------------------------------------------------------------------------------------
示例:使用自定义序列化序列化Dictionary对象
-------------------------------------------------------------------------------------
XML目标
    <?xml version="1.0" encoding="utf-8"?>
    <FactTableDef>
      <Name>FactTableDef1</Name>
      <Owner>owner1</Owner>
      <SourceTable>sourceTable1</SourceTable>
      <ColumnMeasureMaps>
        <Map Column="column1" Measure="Measure1" />
        <Map Column="column2" Measure="Measure2" />
        <Map Column="column3" Measure="Measure3" />
      </ColumnMeasureMaps>
      <ColumnDimensionMaps>
        <Map Column="column4" Dimension="Dimension4" />
        <Map Column="column5" Dimension="Dimension5" />
        <Map Column="column6" Dimension="Dimension6" />
      </ColumnDimensionMaps>
    </FactTableDef>

类源码
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.Serialization;
    using System.Xml;
    using System.Xml.Serialization;

    namespace WZDM.OLAP
    {
        [System.Serializable()]
        [XmlInclude(typeof(FactTableDef))]
        public class FactTableDef : System.Xml.Serialization.IXmlSerializable
        {
            public string Name;               // 名称
            public string Owner;              // 事实表属主
            public string SourceTable;        // 源表
            public Dictionary<string, string> ColumnMeasureMaps;   // 字段和量度对应关系
            public Dictionary<string, string> ColumnDimensionMaps; // 字段和维度对应关系
   
   
            public FactTableDef() { }
            ...
   
            public void WriteXml(System.Xml.XmlWriter writer)
            {
                writer.WriteElementString("Name", this.Name);
                writer.WriteElementString("Owner", this.Owner);
                writer.WriteElementString("SourceTable", this.SourceTable);
   
                // ColumnMeasureMaps
                writer.WriteStartElement("ColumnMeasureMaps");
                foreach (string key in this.ColumnMeasureMaps.Keys)
                {
                    writer.WriteStartElement("Map");
                    writer.WriteAttributeString("Column", key);
                    writer.WriteAttributeString("Measure", ColumnMeasureMaps[key]);
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
   
   
                // ColumnDimensionMaps
                writer.WriteStartElement("ColumnDimensionMaps");
                foreach (string key in this.ColumnDimensionMaps.Keys)
                {
                    writer.WriteStartElement("Map");
                    writer.WriteAttributeString("Column", key);
                    writer.WriteAttributeString("Dimension", ColumnDimensionMaps[key]);
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
            }
   
   
            public void  ReadXml(System.Xml.XmlReader reader)
            {
                reader.Read();
                this.Name = reader.ReadElementString("Name");
                this.Owner = reader.ReadElementString("Owner");
                this.SourceTable = reader.ReadElementString("SourceTable");
   
                // ColumnMeasureMaps
                ColumnMeasureMaps = new Dictionary<string, string>();
                reader.ReadStartElement("ColumnMeasureMaps");
                reader.ReadToDescendant("Map");
                do
                {
                    string key = reader.GetAttribute("Column");
                    string item = reader.GetAttribute("Measure");
                    ColumnMeasureMaps.Add(key, item);
                }while (reader.ReadToNextSibling("Map"));
                reader.ReadEndElement();
   
                // ColumnDimensionMaps
                ColumnDimensionMaps = new Dictionary<string, string>();
                reader.ReadStartElement("ColumnDimensionMaps");
                reader.ReadToDescendant("Map");
                do
                {
                    string key = reader.GetAttribute("Column");
                    string item = reader.GetAttribute("Dimension");
                    ColumnDimensionMaps.Add(key, item);
                } while (reader.ReadToNextSibling("Map"));
                reader.ReadEndElement();
            }
        }
    }

posted @ 2007-03-13 21:57 Kevin Cheng 阅读(4585) | 评论 (6) | 编辑
 

2007年1月15日

解决SSIS连接ODBC数据源时“无法从运行时连接管理器获取托管连接”的问题
      最近尝试采用sqlserver2005 integrate services来做异构数据库之间的数据抽取,使用ODBC连接的Teradata作为数据源。参照《SQL Server 2005数据库开发详解》(电子工业出版社 胡百敬 姚巧玫)P361-363,在SSIS中操作步骤如下:
      (1)在连接管理器中右键-》新建连接-》ODBC,新建odbc连接
      (2)创建DataReader源,右键-》显示高级编辑器-》连接管理器标签-》在连接管理器中选择上步创建的odbc连接.
      到该步后就会报错:“数据流任务 [DataReader 源[1]]出错:无法从运行时连接管理器获取托管连接”
      郁闷啊,反复看这段文字,再查查网上的文章(http://www.yeyan.info/SSIS-sybase-t449843.htm, http://www.yeyan.info/Topic.aspx 等)似乎都没有解决方法。无奈之中,只能尝试下载SQLSERVER SP1 和 Oledb provider for Teradata(地震震断了海底光缆,下得好痛苦啊:<,SP1下载花了3小时,后者至今还未下载成功)。然而,装上SP1后情况依旧。
      只能瞎摸摸了:(,好在终于让我摸成功了:
      (1)在连接管理器中右键-》新建ADO.NET连接-》新建-》.Net提供程序-》Odbc Data Provider
      (2)创建DataReader源,右键-》显示高级编辑器-》连接管理器标签-》在连接管理器中选择上步创建的odbc连接.

      费了俺3天时间,郁闷坏了,好在解决了:-)。《SQL Server 2005数据库开发详解》是本好书,基本面都涉及到了,但细致方面函待加强,这种bug会误人子弟的:-(
posted @ 2007-01-15 13:17 Kevin Cheng 阅读(784) | 评论 (2) | 编辑
 

2006年12月4日

ASP.NET AJAX Control Tookit 使用文档

-----------------------------------------------------------
资源
-----------------------------------------------------------
版本:1.0 Beta 2
官方网站:http://ajax.asp.net/default.aspx?tabid=47&subtabid=477
官方下载网站:http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=AtlasControlToolkit
官方展示网站:http://ajax.asp.net/ajaxtoolkit/


-----------------------------------------------------------
示例代码(以下是根据展示网站整理出来的。持续更新中)
-----------------------------------------------------------
Accordion
    类似OutlookBar的折叠显示效果
     <ajaxToolkit:Accordion
        ID="MyAccordion"
        runat="Server"
        SelectedIndex="0"
        HeaderCssClass="accordionHeader"
        ContentCssClass="accordionContent"
        AutoSize="None">
        FadeTransitions="true"
        TransitionDuration="250"
        FramesPerSecond="40"
        <Panes>
            <ajaxToolkit:AccordionPane
                HeaderCssClass="accordionHeader"
                ContentCssClass="accordionContent">
                <Header> . . . </Header>
                <Content> . . . </Content>
            </ajaxToolkit:AccordionPane>       
            .
            .
            .
        </Panes>           
        <HeaderTemplate>...</HeaderTemplate>           
        <ContentTemplate>...</ContentTemplate>              
        </ajaxToolkit:Accordion>

   
AlwaysVisibleControl
    类似浮动层效果
    <ajaxToolkit:AlwaysVisibleControlExtender ID="ace" runat="server"
        TargetControlID="timer"        
        VerticalSide="Top"
        VerticalOffset="10"
        HorizontalSide="Right"
        HorizontalOffset="10"
        ScrollEffectDuration=".1" />

Animation
    为层的展示添加 Move,Resize,Fade,Color等动画变化效果
    <ajaxToolkit:AnimationExtender ID="ae" runat="server" TargetControlID="ctrl">
        <Animations>
            <OnLoad> ... </OnLoad>
            <OnClick> ... </OnClick>
            <OnMouseOver> ... </OnMouseOver>
            <OnMouseOut> ... </OnMouseOut>
            <OnHoverOver> ... </OnHoverOver>
            <OnHoverOut> ... </OnHoverOut>
        </Animations>
        </ajaxToolkit:AnimationExtender>
   
CascadingDropDown
    局部刷新的级联菜单
    <ajaxToolkit:CascadingDropDown ID="CDD1" runat="server"
        TargetControlID="DropDownList2"
        Category="Model"
        PromptText="Please select a model"
        LoadingText="[Loading models...]"
        ServicePath="CarsService.asmx"
        ServiceMethod="GetDropDownContents"
        ParentControlID="DropDownList1"
        SelectedValue="SomeValue" />
    [WebMethod]
    public CascadingDropDownNameValue[] GetDropDownContents(string knownCategoryValues, string category){...}   

CollapsiblePanel
    可缩放的Panel
     <ajaxToolkit:CollapsiblePanelExtender ID="cpe" runat="Server"
        TargetControlID="Panel1"
        CollapsedSize="0"
        ExpandedSize="300"
        Collapsed="True"
        ExpandControlID="LinkButton1"
        CollapseControlID="LinkButton1"
        AutoCollapse="False"
        AutoExpand="False"
        ScrollContents="True"
        TextLabelID="Label1"
        CollapsedText="Show Details..."
        OpenedText="Hide Details"
        ImageControlID="Image1"
        ExpandedImage="~/images/collapse.jpg"
        CollapsedImage="~/images/expand.jpg"
        ExpandDirection="Height"/>
       
ConfirmButton
    为客户端按钮添加 确认对话框功能
    <ajaxToolkit:ConfirmButtonExtender ID="cbe" runat="server"
        TargetControlID="LinkButton1"
        ConfirmText="Are you sure you want to click this?" />
       
DragPanel
    为层添加可拖动功能
    <ajaxToolkit:DragPanelExtender ID="DPE1" runat="server"
        TargetControlID="Panel3"
        DragHandleID="Panel4" />
   
DropDown
    点击控件后下拉展现指定的层(如菜单)
    <ajaxToolkit:DropDownExtender runat="server" ID="DDE"
        TargetControlID="TextLabel"
        DropDownControlID="DropPanel" />
       
   
DropShadow
    为层添加阴影和圆角效果
    <ajaxToolkit:DropShadowExtender ID="dse" runat="server"
        TargetControlID="Panel1"
        Opacity=".8"
        Rounded="true"
        TrackPosition="true" />
           
   
DynamicPopulate
    由 web service 或 page method 返回的html字符串替换
    <ajaxToolkit:DynamicPopulateExtender ID="dp" runat="server"
        TargetControlID="Panel1"
        ClearContentsDuringUpdate="true"
        PopulateTriggerControlID="Label1"
        ServiceMethod="GetHtml"
        UpdatingCssClass="dynamicPopulate_Updating" />
   
FilteredTextBox
    过滤字符的文本框
     <ajaxToolkit:FilteredTextBoxExtender ID="ftbe" runat="server"
        TargetControlID="TextBox3"        
        FilterType="Custom, Numbers"
        ValidChars="+-=/*()." />
   
HoverMenu
    随光标移动的菜单
    <ajaxToolkit:HoverMenuExtender ID="hme2" runat="Server"
        TargetControlID="Panel9"
        HoverCssClass="popupHover"
        PopupControlID="PopupMenu"
        PopupPosition="Left"
        OffsetX="0"
        OffsetY="0"
        PopDelay="50" />
    <asp:Panel CssClass="popupMenu" ID="PopupMenu"
        runat="server">
        <asp:LinkButton ID="LinkButton1" runat="server"
            CommandName="Edit" Text="Edit" />
        <br />
        <asp:LinkButton ID="LinkButton2" runat="server"
            CommandName="Delete" Text="Delete" />
        </asp:Panel>   

ModalPopup
    灯箱效果(弹出模态对话框,背景变灰且不可操作。类似windows关机)
    <ajaxToolkit:ModalPopupExtender ID="MPE" runat="server"
        TargetControlID="LinkButton1"
        PopupControlID="Panel1"
        BackgroundCssClass="modalBackground"
        DropShadow="true"
        OkControlID="OkButton"
        OnOkScript="onOk()"
        CancelControlID="CancelButton" />
   
MutuallyExclusiveCheckbox
    可互斥的Checkbox
    <ajaxToolkit:MutuallyExclusiveCheckboxExtender runat="server"
        ID="MustHaveGuestBedroomCheckBoxEx"
        TargetControlID="MustHaveGuestBedroomCheckBox"
        Key="GuestBedroomCheckBoxes" />
   
NoBot
    anti-bot技术。用以限制不安全的请求。如:
        InvalidBadResponse        : 不符合流程的响应
        InvalidResponseTooSoon    : 表单填写的时间过快
        InvalidAddressTooActive   : 提交者的IP出现过于频繁
        InvalidBadSession         : 无效的Session客户
        InvalidUnknown            : 其它不安全的请求
    <ajaxToolkit:NoBot
        ID="NoBot2"
        runat="server"
        OnGenerateChallengeAndResponse="CustomChallengeResponse"
        ResponseMinimumDelaySeconds="2"
        CutoffWindowSeconds="60"
        CutoffMaximumInstances="5" />
     
NumericUpDown
    就是Windows控件里面的SpinButton
    <ajaxToolkit:NumericUpDownExtender ID="NUD1" runat="server"
        TargetControlID="TextBox1"
        Width="100"
        RefValues="January;February;March;April"
        TargetButtonDownID="Button1"
        TargetButtonUpID="Button2"
        ServiceDownPath="WebService1.asmx"
        ServiceDownMethod="PrevValue"
        ServiceUpPath="WebService1.asmx"
        ServiceUpMethod="NextValue"
        Tag="1" />
   

PagingBulletedList
    按关键字分组的控件(类似字典)
    <ajaxToolkit:PagingBulletedListExtender ID="PBLE1" runat="server"
        TargetControlID="BulletedList1"
        ClientSort="true"
        IndexSize="1"
        MaxItemPerPage="20"
        Separator=" - "
        SelectIndexCssClass="selectIndex"
        UnselectIndexCssClass="unSelectIndex" />
   

PasswordStrength
    展示输入密码强弱能力的控件
    <ajaxToolkit:PasswordStrength ID="PS" runat="server"
        TargetControlID="TextBox1"
        DisplayPosition="RightSide"
        StrengthIndicatorType="Text"
        PreferredPasswordLength="10"
        PrefixText="Strength:"
        TextCssClass="TextIndicator_TextBox1"
        MinimumNumericCharacters="0"
        MinimumSymbolCharacters="0"
        RequiresUpperAndLowerCaseCharacters="false"
        TextStrengthDescriptions="Very Poor;Weak;Average;Strong;Excellent"
        CalculationWeightings="50;15;15;20" />
   
PopupControl
    点击控件弹出附加窗口。如弹出式日期控件
    <ajaxToolkit:PopupControlExtender ID="PopEx" runat="server"
        TargetControlID="DateTextBox"
        PopupControlID="Panel1"
        Position="Bottom" />
    
   
Rating
    排名控件。用户用鼠标选择星星的个数来代表投票
    <ajaxToolkit:Rating ID="ThaiRating" runat="server"
        CurrentRating="2"
        MaxRating="5"
        StarCssClass="ratingStar"
        WaitingStarCssClass="savedRatingStar"
        FilledStarCssClass="filledRatingStar"
        EmptyStarCssClass="emptyRatingStar"
        OnChanged="ThaiRating_Changed" />
   
ReorderList
    可客户端排序的列表
    <ajaxToolkit:ReorderList ID="ReorderList1" runat="server"
        DataSourceID="ObjectDataSource1"
        DragHandleAlignment="Left"
        ItemInsertLocation="Beginning"
        DataKeyField="ItemID"
        SortOrderField="Priority"
        AllowReorder="true">
          <ItemTemplate>...</ItemTemplate>
          <ReorderTemplate>...</ReorderTemplate>
          <DragHandleTemplate>...</DragHandleTemplate>
          <InsertItemTemplate>...</InsertItemTemplate>
        </ajaxToolkit:ReorderList>


ResizableControl
    可在客户端用鼠标控制控件大小
    <ajaxToolkit:ResizableControlExtender ID="RCE" runat="server"
        TargetControlID="PanelImage"
        HandleCssClass="handleImage"
        ResizableCssClass="resizingImage"
        MinimumWidth="50"
        MinimumHeight="20"
        MaximumWidth="260"
        MaximumHeight="130"
        OnClientResize="OnClientResizeImage"
        HandleOffsetX="3"
        HandleOffsetY="3" />
   

RoundedCorners
    让Panel展现圆角
     <ajaxToolkit:RoundedCornersExtender ID="rce" runat="server"
        TargetControlID="Panel1"
        Radius="6" />
   

Slider
    就是Windows里面的SliderBar,有水平和垂直两种样式
    <ajaxToolkit:SliderExtender ID="SliderExtender1" runat="server"
        TargetControlID="Slider1"
        Minimum="-100"
        Maximum="100"
        BoundControlID="Slider1_BoundControl"
        Steps="5" />
    <ajaxToolkit:SliderExtender ID="SliderExtender2" runat="server"
        TargetControlID="Slider2"
        BoundControlID="Slider2_BoundControl"
        Orientation="Vertical"
        EnableHandleAnimation="true" />
   

TextBoxWatermark
    输入框水印效果:为输入框提供默认文字和背景,在用户鼠标点击或者悬停后,清空背景及文字
    <ajaxToolkit:TextBoxWatermarkExtender ID="TBWE2" runat="server"
        TargetControlID="TextBox1"
        WatermarkText="Type First Name Here"
        WatermarkCssClass="watermarked"
        HasInitialFocus="false" />
   

ToggleButton
    将CheckBox用图像替代
    <ajaxToolkit:ToggleButtonExtender ID="ToggleEx" runat="server"
        TargetControlID="CheckBox1"
        ImageWidth="19"
        ImageHeight="19"
        CheckedImageAlternateText="Check"
        UncheckedImageAlternateText="UnCheck"
        UncheckedImageUrl="ToggleButton_Unchecked.gif"
        CheckedImageUrl="ToggleButton_Checked.gif"
        DisabledUncheckedImageUrl="ToggleButton_DisabledUnchecked.gif"
        DisabledCheckedImageUrl="ToggleButton_DisabledChecked.gif" />
   
   
UpdatePanelAnimation 
     为Panel添加提交时的动画效果。如fade, collapse, Colorlize
    <ajaxToolkit:UpdatePanelAnimationExtender ID="ae" runat="server" TargetControlID="up">
        <Animations>
            <OnUpdating> ... </OnUpdating>
            <OnUpdated> ... </OnUpdated>
        </Animations>
        </ajaxToolkit:UpdatePanelAnimationExtender>

ValidatorCallout 
    美化版的客户端数据验证
    <ajaxToolkit:ValidatorCalloutExtender
        runat="Server"
        ID="PNReqE"
        TargetControlID="PNReq"
        Width="350px"
        HighlightCssClass="highlight"
        WarningIconImageUrl="warning.gif"
        CloseImageUrl="close.gif" />
   

posted @ 2006-12-04 00:45 Kevin Cheng 阅读(5387) | 评论 (2) | 编辑
 

2006年11月7日

相面
今天碰上个老和尚、一个小和尚,在酒店里面吃早餐时拉我聊天
夸俺菩萨相啊,好运将多年,年底有贵人相助啊什么的
心慈面善啊什么的,有好报啊什么的,真夸得我心花怒放
还说印堂发亮,面带贵气,日后财富不缺什么的
眉毛左高右低,有贤内助什么的
哇哈哈哈,真是善良的老和尚
再说点小缺点,言需慎重,行要果断什么的
然后再拿出一张佛铜片,说什么开光了什么的
说有缘,没什么可相送的,就送我这张开光佛片什么的,日后找他相助什么的
然后给我他的法号地址,拿个本子让我记我的地址,要点香火钱回寺后给我烧三柱香什么的
然后....我就跑了,实在很惭愧
也许人家出于善意和缘分,相面相得很准,要点香火钱是为了可持续发展什么的?
所以我越想越惭愧什么的...
posted @ 2006-11-07 22:21 Kevin Cheng 阅读(465) | 评论 (3) | 编辑
 

2006年10月10日

CustomValidator 的客户端验证

定制验证控件
    <asp:customvalidator id="cvRequestUnit" runat="server"
        ControlToValidate="cmbRequestUnit"
        ErrorMessage="请选择投诉单位"
        Display="Dynamic"
        ClientValidationFunction="ClientValidate"
        />

被验证对象
    <asp:dropdownlist id="cmbRequestUnit" runat="server"></asp:dropdownlist>

客户端验证
    // 验证文本框值(必须是偶数)
    function ClientValidate(src, args)
    {
     var val = args.Value;
     args.IsValid = (val mod 2 == 0);
    }
    // 验证下拉框值(不等于-1)
    function ClientValidate(src, args)
    {
     var val = args.Value; //或者cmbRequestUnit.value;
     args.IsValid = (val != "-1");
    }

    注:其中客户端验证函数必须带有两个参数
        src :存储验证控件
        args : 存储验证参数
            由结构体封装:
                 var args = { Value:value, IsValid:true }; (摘自WebUIValidation.js)
            其中:
                Value(string类型)来源于被验证控件的value属性:
                IsValid(boolean类型)必须在验证函数结束前赋值返回

 

posted @ 2006-10-10 12:29 Kevin Cheng 阅读(1130) | 评论 (1) | 编辑
 

2006年9月12日

使用安全配置向导降低Win2003内存消耗[原]

    Win2003好用是好用,就是内存耗得厉害,安装完SP1后正常内存消耗是200M左右,像我这种老机是吃不消滴。当然,关闭不常用的服务就可以减少内存消耗,但直接使用服务管理器还是太难操作了(服务间的依赖就像千年老树一样盘根错杂)。其实,可以使用SP1带的“安全配置向导”来帮助你完成这个工作:

(1)安装“安全配置向导”:添加或删除程序 -> 添加/删除Windows组件 -> 安全配置向导
(2)使用“安全配置向导”:管理工具 -> 安全配置向导。绝大部分都默认下去。

待完成后重启,系统用的内存会降到110M左右,和WINXP差不多了哇哈哈哈

posted @ 2006-09-12 01:34 Kevin Cheng 阅读(693) | 评论 (2) | 编辑
 

2006年8月29日

用代码获取Oracle服务名清单

        /*
        获取Oracle服务名
        1。查询注册表,获取oracle安装根目录
            如:HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\ORACLE_HOME   REG_SZ  E:\ORACLE\ORA92
            得知oracle服务名文件所在地:根目录\network\ADMIN\tnsnames.ora
           
        2。解析该文件,该文件结构如
            # ------------------------------------------------
            PORTAL =
            (DESCRIPTION =
                (ADDRESS_LIST =
                (ADDRESS = (PROTOCOL = TCP)(HOST = 134.104.52.6)(PORT = 1521))
                )
                (CONNECT_DATA =
                (SERVICE_NAME = portal)
                )
            )

        3。解析要点:
            一行一行获取再解析
            跳过以#打头的注释行
            过滤掉空格后,首字符在A~z之间的行就包含了Oracle服务名
            截取该行第一个“=”号左边的字符串,trim处理后就是Oracle服务名了
        */
        public static string[] GetOracleTnsNames()
        {
            try
            {
                // 查询注册表,获取oracle服务文件路径
                RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("ORACLE");
                string home = (string)key.GetValue("ORACLE_HOME");
                string file = home + @"\network\ADMIN\tnsnames.ora";

                // 解析文件
                string line;
                ArrayList arr = new ArrayList();
                StreamReader sr = new StreamReader(file);
                while ((line = sr.ReadLine()) != null)
                {
                    line = line.Trim();
                    if (line != "")
                    {
                        char c = line[0];
                        if ( c>= 'A' && c<='z')
                            arr.Add(line.Substring(0, line.IndexOf(' ')));
                    }
                }
                sr.Close();

                // 返回字符串数组
                return (string[])arr.ToArray(typeof(string));
            }
            catch (Exception ex)
            {
                return null;
            }
        }

posted @ 2006-08-29 18:36 Kevin Cheng 阅读(617) | 评论 (0) | 编辑
 

2006年8月10日

哈哈,过了系统分析员,发文庆祝一下
考试前狠狠的复习了一天,将去年的两份试题都做会了,弄到凌晨3点,8点钟爬去考试,熬到最后一分钟交卷,终于高中,考得还不错,哇哈哈哈~,发文庆祝一下。唯一的遗憾是公司对这个冬冬不感冒55555。
posted @ 2006-08-10 10:44 Kevin Cheng 阅读(382) | 评论 (4) | 编辑
 
台风“桑美”至

2006-08-10 10:27
温州是个台风多发地域,一入夏就警报连连。超强“桑美”估计中下午登陆温州地区,今晨还是雨点连连混天黑地,临近中午时分反而雨歇风停天空放亮,颇有大战前夕的压迫感。(附温州气象台对桑美的描述:中心气压915百帕,近中心最大风力17级(60米/秒)。目前超强台风中心正以每小时25公里左右的速度朝西北偏西方向移动,预计超强台风“桑美”将于今天中午到上半夜在霞浦到乐清湾一带沿海登陆,正面袭击我市,受其影响,今天我市沿海海面风力将有8—10级并逐渐加强到12级以上,超强台风中心经过的附近地区将有14—16级大风,今天我市内陆地区也将有10—1...)Kevin于台风第一线温州现场报道哈哈

2006-08-10 16:10
不知不觉,天已经黑下来了,已酝酿了许久的“桑美”以她特有的步法不紧不慢的逼近温州。风力渐大,穿过罅缝呜呜作响。街道上人车多是慌慌张张,都往家赶。市长上午已公告市民,如有必要避免外出,并做好抗台工作。头已许可提前下班,心慌慌,偶也要赶快回家了~

2006-08-10 17:40
偶终于到家了,感动啊~。众望所归,台风桑美终于露出她狰狞的爪爪,正面吞没了温州
好一个风雨交加,风是无向风,雨是横扫雨,破伞满街掷,垃圾桶满地滚,咣当当,咣当当
大街上,风吹无声,雨落隆隆。道路边,单薄美眉,伞撑不住。
的已打不到,众多公车已停开,最糟糕的是俺没有小车,难道光脚跑路?
一回家,周身衣物尽扒下。关紧窗,窗台横扫雨滴答。
早闻道,夕死可以,看来我可以圆满了。台风刚至,我就得知三样东西是正确的:
·杭州天堂伞质量不错,经住了考验
·温州公交5路车是值得大家信赖的,没有停开
·米子外买敬业无比,台风起兮,便当仍至

2006-08-11
真不愧是40年一遇的台风,在苍南登陆时中心风力达到17级(每秒60米),桑美卷走了100多条人命,苍南损失惨重....

posted @ 2006-08-10 10:29 Kevin Cheng 阅读(285) | 评论 (0) | 编辑
 

2006年6月29日

Gentle.NET Users' Guide

------------------------------------------------------------
用户指南 - Gentle.NET 概述
------------------------------------------------------------
1. 什么是持续框架(PersisitenceFramework)?
    将对象映射到关系数据库的一种快速开发框架
    理论背景,可参考
        ·持续化思想http://www.ambysoft.com/downloads/persistenceLayer.pdf
        ·OR映射:http://www.agiledata.org/essays/impedanceMismatch.html
        ·NULL值处理:
    附加信息
        ·微软进行持续框架研究(ObjectSpaces)已经好几年了,但很不幸的是,它被无限期延后了(最新的消息是在Loghorn服务器在2007年发布时,它将随WinFS一起被提供)
        ·然而,关于持续框架是什么,为什么你需要使用它,微软提供了比较有用的背景信息,可以参看http://www.15seconds.com/issue/040112.htm
2. Gentle概述
    ·metadata(attributes and database schema analysis)
    ·business object(base classes and interfaces)
    ·architecture (framework and database access)
    ·encapsulating parameters (criteria and object identifiers)
    ·custom queries
    ·query results(and object construction)
    ·presentation (custom dataview generation)
    ·transactions

3. 使用 Gentle.NET
3.1 基本例程
    using Gentle.Framework;

    [TableName("Users")]
    public class User : Persistent
    {
        private int userId;
        private string userName;
        // this is used by clients to construct new users
        public User( string userName ) : this( 0, userName ) {}
        // this is used by Gentle to reconstruct objects read from the database
        public User( int userId, string userName )
        {
            this.userId = userId;
            this.userName = userName;
        }
        [TableColumn("UserId"), PrimaryKey(AutoGenerated=true)]
        public int Id
        {
            get{ return userId; }
            set{ userId = value; }
        }
        [TableColumn(NotNull=true)]
        public string Name
        {
            get{ return userName; }
            set{ userName = value; }
        }

        //----------------------------------------------------------       
        // this is used by client to fetch users from the database
        static public User Retrieve( int userId )
        {
            Key key = new Key( typeof(User), true, "Id", userId );
            return Broker.RetrieveInstance( typeof(User), key ) as User;
        }
    }

    User user = new User( 42, "Ford Prefect" );
    Broker.Insert( user ); // 把user对象保存到数据库
    Key key = new Key( typeof(User), true, "Id", 42 ); // 使用单项选择限制条件值来创建关键字(create a key with a single selection criteria value)
    user = Broker.RetrieveInstance( typeof(User), key ) as User; // 重数据库获取指定user对象(load the specified user from the database)

    // 若User继承至Persistent,可以简化为:
    User ford = new User( "Ford Prefect" );
    ford.Persist(); // 保存新user并分配了id
    User prefect = User.Retrieve( ford.Id ); // 获取指定user

 

3.2 获取列表
    获取所有user对象实例
        static public IList ListAll
        {
            get{ return Broker.RetrieveList( typeof(User) ); }
        }
    定制查询
        static public IList ListByNameStartsWith( string partialName )
        {
            SqlBuilder sb = new SqlBuilder( StatementType.Select, typeof(User) );
            // note: the partialName parameter must also contain the %'s for the LIKE query!
            sb.AddConstraint( Operator.Like, "Name", partialName );
            // passing true indicates that we'd like a list of elements, i.e. that no primary key
            // constraints from the type being retrieved should be added to the statement
            SqlStatement stmt = sb.GetStatement( true );
            // execute the statement/query and create a collection of User instances from the result set
            return ObjectFactory.GetCollection( typeof(User), stmt.Execute() );
        }

3.3 用GentleList来处理关联
    GentleList继承至从ArrayList,与普通的list很相似,并添加了持续化保存得特性.
    它支持以下类型的关联: StandAlone, OneToMany, ManyToMany
        ·standAlone
            GentleList list = new GentleList( typeof(User) );
        ·OneToMany
            GentleList list = new GentleList( typeof(User), parentInstance );
        ·ManyToMany
            GentleList list = new GentleList( typeof(User), role, typeof(UserRole) );


3.4 关联
    获取与account相关联的account对象列表
    public IList Accounts
    {
        get{ return RetrieveList( typeof(Account), "Id" ); }
    }

    外键关联
    [TableColumn("SubscriberId"), PrimaryKey, ForeignKey("User","UserId")]
    public int SubscriberId
    {
        get{ return subscriberId; }
        set{ subscriberId = value; }
    }

3.5 用MagicValue来处理NULL值
    int等类型不允许赋null值,而数据库中对应的字段是允许的,如何处理这种映射?
    注:c#2.0中提供允许空的数值类型
    在Gentle.Net中使用MagicValue来处理这种转化
        数值类型.null<-->null字段
        DateTime.Min <-->null字段,但很多数据库不支持datatime类型,很可能被截断。比较危险
    例程
        [TableColumn("id", NotNull=true), PrimaryKey(AutoGenerated=true)]
        protected int id;
        [TableColumn("name", NullValue="")]
        protected string name;
        [TableColumn("remark", NullValue="")]
        protected string remark;
 
    例程http://www.mertner.com/svn/repos/projects/gentle/Source/Gentle.Framework.Tests/BusinessObjects/PropertyHolder.cs
        [TableColumn( NotNull=false, NullValue=-1 )]
        public int TInt
        {
            get { return _int; }
            set { _int = value; }
        }

        [TableColumn( NotNull=false, NullValue=NullOption.MinValue )]
        public decimal TDecimal
        {
            get { return _decimal; }
            set { _decimal = value; }
        }

        // note: this field can be null
        // setting here is wrong for the purpose of testing SqlAnalyzer override
        [TableColumn( NotNull=true, NullValue=0 )]
        public double TDouble
        {
            get { return _double; }
            set { _double = value; }
        }
       
        [TableColumn( NotNull=false )]
        public DateTime TDateTime
        {
            get { return _datetime; }
            set { _datetime = value; }
        }
    对可空类型的支持尚在日程表中,但还不是很紧迫。可以到JIRA查看开发进度
    http://www.mertner.com/jira/browse/GOPF-30


3.6 创建DataView
    不再推荐使用ObjectView类。请在数据绑定时使用TypedArrayList和TypedArrayItemBase来定制对象的展示
 
3.7 同步控制
    Gentle.Net提供行级别得同步控制,来取保数据完整性
    为了使用同步控制功能,需要添加一个integer类型字段,并在代码中赋予Concurrency特性。
    当你尝试更新一个过期数据时,gentle会抛出异常Error.Recordchanged。故必须封装所有更新操作捕获该错误。
    如果你使用Persistent作为基类,通过创建自己的基类并重载更新方法来实现它?
    可以使用Refresh方法来修复同步错误(在Persistent,PersistenceBroker和Broker类中),它会重新获取新数据,再重新调用更新操作
 
3.8 缓存(Caching)和 唯一性(Uniqing)
    (1)出于提高性能考虑而采取的策略
    (2)缓存配置
            DefaultStragegy = Temporary | Never | Permanent
            CacheStatements = true | false
            CacheObjects    = false | true
            SkipQueryExecution = false | true
            UniqingScope    = Thread | Application | WebSession
         缓存配置例子
            <Cache>
                <DefaultStrategy>Temporary</DefaultStrategy>
                <CacheStatements>true</CacheStatements>
                <CacheObjects>true</CacheObjects>
                <SkipQueryExecution>false</SkipQueryExecution>
                <UniqingScope>Thread</UniqingScope>
            </Cache>
         SqlStatement对象的缓存:GentleNet自动缓存所有statement对象
         对象的缓存
         QuerySkipping
            当开启SkipQueryExecution时,Gentle将缓存查询结果信息
            若该信息在先前已被缓存,则gentle使用已缓存的对象来构建查询结果,这样就免去了数据库操作,大大改善了查询性能。严重推荐。
    (3)对象唯一性(Object Uniqing)
        使用对象唯一性,就不必操作多个内存对象来描述同一数据库行。
        这不仅是一种节省内存的机制,也有助于防止数据不一致
    (4)对象缓存和唯一性带来的线程安全问题
        然而,既然使用了对象缓存和唯一性,某个线程就可以使用另外一个线程使用的对象引用,这就引进了线程安全性问题
        为了解决这种问题,gentle提供了UniqingScope设置,用于将缓存和唯一性特性限制到应用程序范畴(Application Scope)或线程范畴(Thread Scope)
            ·应用程序范畴:在统一AppDomain中的对象使用相同的缓存
            ·线程范畴:每个线程使用自己的缓存
        线程范畴保证了线程安全,当如果在每个线程中都创建很多对象的话,缓存机制就没有什么意义了
        故,通常对于ASP.NET应用程序使用线程范畴,而其它使用应用程序范畴。
    (5)监控缓存使用情况(Monitoring)
        GentleStatistics.LogStatistics( LogCategory.Cache )
    (6)提示和窍门
        使用Gentle.Common.CachedManager类
            例如,可以使用它将对象永久保存在内存。
            该类非常有用,例如缓存custom IGentleProvider或PersistenceBroker对象,Gentle自动确保它们不会被垃圾收集所释放
            在ASP.NET应用程序中,需要维护一个键用于保存缓存中的项目,例如创建一个guid并将它保存在session中或保存在页面的ViewState变量中。
            当然,必须小心使用永久缓存对象功能,要是你不告诉CacheManager,它们将永久保存在缓存中

3.9 验证Validation
    Gentle验证框架提供了程序验证公用层(common layer)
    提供的验证器
        RegexValidator         [RegexValidator(Express=@"[A-Z]+[a-..."]
        RequiredValidator      [RequiredValidator()]
        RangeValidator         [RangeValidator(Min=20.5, Max=100.5)]
    自定义验证器
        需要扩展ValidatorBaseAttribute或实现在Validate方法中被调用的IValidationPersistent接口
        该方法在更新和新建时被调用

4 OR 映射技术
    遗传映射(Inheritance Mapping)
        Gentle使用“一个类,一张表”的方法来实现对象层次映射
            这种方法最早被实现并很好的实现了,是最主要的方法
            这意味着任何类都对应一种表
            当对象无关联并不共享字段时,这种方法干得不错
            是一种“平”对象继承(flat object hierachy)
            可参考这篇非常棒的文章:http://www.agiledata.org/essays/mappingObjects.html#MapEachClassToTable
        也可以使用多个类映射到单张表
            用一个字段来存储记录类型,该字段必须标注TableColumn和Inheritance特性
            如果你有许多有共享字段且相关联的类,这种方法是比较有用的。
            When you select the classes, gentle will filter out rows that are not the specified type itself or a descendant of it.
            可以查看测试项目中的MultiType.cs 和 TestMultiType.cs 文件,看看他们是如何工作的:
            [TableName( "MultiType" )]
            public abstract class MultiType : Persistent
            {
                [TableColumn, PrimaryKey( AutoGenerated=true ), SequenceName( "MULTITYPE_SEQ" )] protected int id = 0;
                [TableColumn, Inheritance] protected string type;
                [TableColumn] protected int field1 = 1;
                [TableColumn] protected decimal field2 = 2;
                [TableColumn] protected double field3 = 3;
                [TableColumn] protected string field4 = "4";
       
                public MultiType()
                {
                }
       
                public static object Retrieve( Type t, int id )
                {
                    Key key = new Key( t, true, "id", id );
                    return Broker.RetrieveInstance( t, key );
                }
       
                public static MultiType Retrieve( int id )
                {
                    Key key = new Key( typeof(MultiType), true, "id", id );
                    return Broker.RetrieveInstance( typeof(MultiType), key ) as MultiType;
                }
       
                public int Id
                {
                    get { return id; }
                }
                public string Type
                {
                    get { return type; }
                }
            }
       
            [TableName( "MultiType" )]
            public class Animal : MultiType
            {
                new public static Animal Retrieve( int id )
                {
                    return Retrieve( typeof(Animal), id ) as Animal;
                }
            }
       
            [TableName( "MultiType" )]
            public class Dog : Animal
            {
                new public static Dog Retrieve( int id )
                {
                    return Retrieve( typeof(Dog), id ) as Dog;
                }
            }
       
            [TableName( "MultiType" )]
            public class Cat : Animal
            {
                new public static Cat Retrieve( int id )
                {
                    return Retrieve( typeof(Cat), id ) as Cat;
                }
            }           
        Aggeregated Object
            将单个类映射到一个或多个父类的字段
            例子:Money类具有Currency和Amount属性
            不太明白p34
        动态表映射
            在类中通过实现ITableName接口来重载表名(在TableName特性中设置)
            若你的类中实现了该接口,Gentle会检测到,以访问不同的表
性能考虑
    数据库分析
        gentle使用特性attributes(曾用xml来支持)来映射metadata和数据库
    对象创建
        gentle可以使用几乎所有有效的构造器来创建对象,并且,对于列数组,gentle将自动的采用最低成本的构造方式。
        创建成本是以下方面的总和:p36
    缓存(Caching)
    性能比较

                           
------------------------------------------------------------
使用MyGeneration-Gentle.NET 业务实体模板
------------------------------------------------------------
MyGeneration:http://www.mygenerationSoftWare.com
BusinessEntity.csgen(Gentle.NET Business Entity $Rev:942$)


 

posted @ 2006-06-29 16:17 Kevin Cheng 阅读(916) | 评论 (4) | 编辑
 
Gentle.NET Attribute

------------------------------------------------------------
Gentle.NET Attribute
------------------------------------------------------------
数据表特性(用在实体类上)
    [TableName("Product", CacheStrategy.Temporary)]
    注:缓存策略
        public enum CacheStrategy
        {
            Never,           // 每次都直接从数据库获取记录
            Temporary,       // 读取记录后丢到Cache中,并指定失效时间。每次查询时先尝试从cache中获取,若不存在才查询数据库
            Permonent        // 类似Tempory,但不指定失效时间
        }


数据字段特性
    针对不同的数据库以下特性部分有效,具体请查看pdf文档Page55-57
        [Size]
        [Type]
        [IsNullable]
        [IsUnique]
        [IsPrimaryKey]
        [IsForeignKey]
        [IsAutoGenerated]
    例如:主键,自增字段
  [TableColumn("id", NotNull=true), PrimaryKey(AutoGenerated=true)]
  protected int id;
  [TableColumn("name", NullValue="")]
  protected string name;

     [TableColumn( "ph_Id", NotNull=true ), PrimaryKey( AutoGenerated=true ), SequenceName( "PROPERTYHOLDER_SEQ" )]
     public virtual int Id
     {
      get { return id; }
      set { id = value; }
     }
    Gentle.Framework Attribute
        [Concurrency]
        [CustomView]
        [ForeignKey]
        [Inheritance]
        [PrimaryKey]
        [SequenceName]
        [SoftDelete]
        [TableColumn]
        [TableName]


数据视图特性(用在Property上)Gentle.Common.Attributes
    以下特性可用在Property上
        [Caption("Caption")]
        [AllowSort(false)]
        [ReadOnly(false)]
        [Visible(false)]
    例如   
        [Caption("Company"), ReadOnly(true)]
        property string CompanyName
        {
            get{ return companyName; }
            set{ companyName = value; }
        }
        [AllowSort(false)]
        public string Name
        {
            get { return mName; }
            set { mName = value; }
        }
        [Visible(false)]
        public string Name
        {
            get { return mName; }
            set { mName = value; }
        }

数据校验特性 
    [RegexValidator(Expression=@"[A-Z]+[a-z])]
    [RequiredValidator()]
    [RangeValidator( Min=20.5, Max=100.5 )]
 

 

posted @ 2006-06-29 16:14 Kevin Cheng 阅读(304) | 评论 (0) | 编辑
 
仅列出标题  下一页