<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_梁利锋</title><subtitle type="text"/><id>http://feed.cnblogs.com/blog/u/60359/rss</id><updated>2011-12-28T14:13:19Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/60359/rss"/><entry><id>http://www.cnblogs.com/lephone/archive/2011/12/28/dbentry4_1.html</id><title type="text">DbEntry.Net 4.1</title><summary type="text">这是我设计的一个轻量级的 .Net ORM (Object Relational Mapping) 数据访问及 WEB 框架。对于 ORM 和 Sql 调用，它都拥有清晰和易用的接口，目前支持 SqlServer、SQLite、MySql、Access、Firebird、PostgreSQL、Oracle 等数据库。对于 WEB 开发，它既支持 ASP.NET 2.0 的 DataSource 方式，也支持 Ruby On Rails 风格的 MVC 方式。支持 Linq 方式的查询，也提供一个简单的 IoC。 目前，数据库部分已经支持多主键、多表联合查询、快速分页、隐式数据库事务、连贯...</summary><published>2011-12-28T14:13:00Z</published><updated>2011-12-28T14:13:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2011/12/28/dbentry4_1.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2011/12/28/dbentry4_1.html"/><content type="html">&lt;p&gt;这是我设计的一个轻量级的 .Net ORM (Object Relational Mapping) 数据访问及 WEB 框架。对于 ORM 和 Sql 调用，它都拥有清晰和易用的接口，目前支持 SqlServer、SQLite、MySql、Access、Firebird、PostgreSQL、Oracle 等数据库。对于 WEB 开发，它既支持 ASP.NET 2.0 的 DataSource 方式，也支持 Ruby On Rails 风格的 MVC 方式。支持 Linq 方式的查询，也提供一个简单的 IoC。&lt;br /&gt;&lt;br /&gt;目前，数据库部分已经支持多主键、多表联合查询、快速分页、隐式数据库事务、连贯API查 询、ActiveRecord风格查询、动态对象、部分保存、自动创建数据表、一对一、一对多、多对多关系等功能，具体实现请参阅 Samples 中的例子程序和单元测试的内容。&lt;br /&gt;&lt;br /&gt;而 DataSource 部分，因为绑定数据访问组件，所以可以只需要修改配置文件，不需要修改任何代码的在不同的数据之间切换。另外，还支持按命名约定的方式绑定&amp;ldquo;新建&amp;rdquo;和&amp;ldquo;编辑&amp;rdquo;页面的控件，以最少的代码完成输入、验证、保存等一系列操作。&lt;br /&gt;&lt;br /&gt;Rails 风格的 MVC 框架目前已经完成 MVC 部分，脚手架，基类中的 LinkTo、UrlTo 等快捷函数，Http Get 支持等。目前脚手架部分没有数据验证模块，不过，自己写的 MVC 代码可以自行实现验证。&lt;br /&gt;&lt;br /&gt;　 　这个版本中，例子程序访问的数据库主要是 Access，而单元测试使用的数据库是 SQLite，通过修改配置文件中数据源部分，可以使之不需要重新编译即可工作于其它数据库上。配置部分通过 App.config 进行，请参阅 Samples 中的例子程序中的 App.config 和 UnitTest 项目内嵌的配置文件 UnitTest.config.xml 。所有例子程序在 MS Sql Server 2005 Express、MS Sql Server 2008 Express、 MS Access 2003、MySql 5.0、SQLite 3、Firebird 2.1.0, PostgreSQL 8.3.3 和 Oracle 10g Express 上测试过。&lt;br /&gt;&lt;br /&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/83760/2011052422171998.png" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;v4.1 版主要的改变为：&lt;br /&gt;&amp;middot;增加 QueryRequired 功能；&lt;br /&gt;&amp;middot;更严格的编译时检查；&lt;br /&gt;&amp;middot;Model 增加可覆盖的 OnInserting、OnUpdating、OnDeleting；&lt;br /&gt;&amp;middot;重新整理 DbEntryDataSource 的事件；&lt;br /&gt;&amp;middot;增加 ConditionBuilder；&lt;br /&gt;&amp;middot;增加 NotIn 支持；&lt;br /&gt;&amp;middot;增加 LoadRelation 函数；&lt;br /&gt;&amp;middot;Bug 修正 ；&lt;/p&gt;&lt;p&gt;&lt;br /&gt;下载本组件和浏览文档请访问 &lt;a href="http://www.codeplex.com/DbEntry/" target="_blank"&gt;http://www.codeplex.com/DbEntry/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/2305432.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2011/12/28/dbentry4_1.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2011/05/24/dbentry4_0.html</id><title type="text">DbEntry.Net 4.0</title><summary type="text">这是我设计的一个轻量级的 .Net ORM (Object Relational Mapping) 数据访问及 WEB 框架。对于 ORM 和 Sql 调用，它都拥有清晰和易用的接口，目前支持 SqlServer、SQLite、MySql、Access、Firebird、PostgreSQL、Oracle 等数据库。对于 WEB 开发，它既支持 ASP.NET 2.0 的 DataSource 方式，也支持 Ruby On Rails 风格的 MVC 方式。支持 Linq 方式的查询，也提供一个简单的 IoC。 目前，数据库部分已经支持多主键、多表联合查询、快速分页、隐式数据库事务、连贯AP.</summary><published>2011-05-24T14:22:00Z</published><updated>2011-05-24T14:22:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2011/05/24/dbentry4_0.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2011/05/24/dbentry4_0.html"/><content type="html">&lt;p&gt;这是我设计的一个轻量级的 .Net ORM (Object Relational Mapping) 数据访问及 WEB 框架。对于 ORM 和 Sql 调用，它都拥有清晰和易用的接口，目前支持 SqlServer、SQLite、MySql、Access、Firebird、PostgreSQL、Oracle 等数据库。对于 WEB 开发，它既支持 ASP.NET 2.0 的 DataSource 方式，也支持 Ruby On Rails 风格的 MVC 方式。支持 Linq 方式的查询，也提供一个简单的 IoC。&lt;br /&gt;&lt;br /&gt;目前，数据库部分已经支持多主键、多表联合查询、快速分页、隐式数据库事务、连贯API查询、ActiveRecord风格查询、动态对象、部分保存、自动创建数据表、一对一、一对多、多对多关系等功能，具体实现请参阅 Samples 中的例子程序和单元测试的内容。&lt;br /&gt;&lt;br /&gt;而 DataSource 部分，因为绑定数据访问组件，所以可以只需要修改配置文件，不需要修改任何代码的在不同的数据之间切换。另外，还支持按命名约定的方式绑定&amp;ldquo;新建&amp;rdquo;和&amp;ldquo;编辑&amp;rdquo;页面的控件，以最少的代码完成输入、验证、保存等一系列操作。&lt;br /&gt;&lt;br /&gt;Rails 风格的 MVC 框架目前已经完成 MVC 部分，脚手架，基类中的 LinkTo、UrlTo 等快捷函数，Http Get 支持等。目前脚手架部分没有数据验证模块，不过，自己写的 MVC 代码可以自行实现验证。&lt;br /&gt;&lt;br /&gt;这个版本中，例子程序访问的数据库主要是 Access，而单元测试使用的数据库是 SQLite，通过修改配置文件中数据源部分，可以使之不需要重新编译即可工作于其它数据库上。配置部分通过 App.config 进行，请参阅 Samples 中的例子程序中的 App.config 和 UnitTest 项目内嵌的配置文件 UnitTest.config.xml 。所有例子程序在 MS Sql Server 2005 Express、MS Sql Server 2008 Express、 MS Access 2003、MySql 5.0、SQLite 3、Firebird 2.1.0, PostgreSQL 8.3.3 和 Oracle 10g Express 上测试过。&lt;br /&gt;&lt;br /&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/83760/2011052422171998.png" /&gt;&lt;br /&gt;&lt;br /&gt;v4.0 版主要的改变为：&lt;br /&gt;&amp;middot;更新到 .Net 4.0；&lt;br /&gt;&amp;middot;支持使用动态对象返回结果集；&lt;br /&gt;&amp;middot;改为不使用 abstract 的方式；&lt;br /&gt;&amp;middot;不使用内存程序集，而是直接修改程序集；&lt;br /&gt;&amp;middot;对于 Model 使用的 DbContext 改为使用属性定义；&lt;br /&gt;&amp;middot;增加对于 ComposedOf 的支持；&lt;br /&gt;&amp;middot;结构调整，Bug 修改等；&lt;br /&gt;&lt;br /&gt;下载本组件和浏览文档请访问 &lt;a target="_blank" href="http://www.codeplex.com/DbEntry/"&gt;http://www.codeplex.com/DbEntry/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/2056046.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2011/05/24/dbentry4_0.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/12/23/analyze_simple_script_engine.html</id><title type="text">《点睛简单脚本引擎》源代码导读 —— 原型、命令模式应用</title><summary type="text">这篇文章，是2004年写的，本来没准备再重发，今天因为一些事，翻了出来，鉴于现在仍然有很多人停留在YY工厂模式和单件模式上，另外，我觉得这篇文章和所涉及的代码写的还是挺不错的，所以重发出来，个人觉得，还是有意义的。前几天，和朋友谈论《点睛简单脚本引擎》的代码，发现，其实还是需要讲解一下，特别是说明为什么这种方式比直观的代码编写更好。脚本本身的格式比较简单，所有的参数用“|”分隔，第一个参数是命令名，如果命令名为空，则此行被视为“注释”。从类图来看代码结构就非常清晰了，其中，黄色的类是“静态类”，也就是只包含一些静态函数的类；而粉色的类是“自定义异常”；青色的类是“接口”；淡绿色的类</summary><published>2010-12-23T05:40:00Z</published><updated>2010-12-23T05:40:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/12/23/analyze_simple_script_engine.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/12/23/analyze_simple_script_engine.html"/><content type="html">&lt;p&gt;&lt;em&gt;这篇文章，是2004年写的，本来没准备再重发，今天因为一些事，翻了出来，鉴于现在仍然有很多人停留在YY工厂模式和单件模式上，另外，我觉得这篇文章和所涉及的代码写的还是挺不错的，所以重发出来，个人觉得，还是有意义的。&lt;/em&gt;&lt;/p&gt;&lt;p&gt;前几天，和朋友谈论《点睛简单脚本引擎》的代码，发现，其实还是需要讲解一下，特别是说明为什么这种方式比直观的代码编写更好。&lt;/p&gt;&lt;p&gt;脚本本身的格式比较简单，所有的参数用&amp;ldquo;|&amp;rdquo;分隔，第一个参数是命令名，如果命令名为空，则此行被视为&amp;ldquo;注释&amp;rdquo;。&lt;/p&gt;&lt;p&gt;从类图来看代码结构就非常清晰了，其中，黄色的类是&amp;ldquo;静态类&amp;rdquo;，也就是只包含一些静态函数的类；而粉色的类是&amp;ldquo;自定义异常&amp;rdquo;；青色的类是&amp;ldquo;接口&amp;rdquo;；淡绿色的类是普通的类。我们先来看一下类图：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2010/83760/2010122313272847.gif" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;其中，ApplicationEntry 是程序的入口点，其中的 Main 函数创建一个 ProcessorControlCenter 的实例，并且执行它的 RunScript 函数。而 ProcessorControlCenter 中的 RunScript 函数也很简单，只是使用了 ProcessorFactory 创建出一个 CallScriptProcessor，并且执行它的 DoProcessor 函数。&lt;/p&gt;&lt;p&gt;最基本的接口是一个 IProcessor 接口，包含一个 DoProcess 函数，然后 IProcessorInstance 继承了 IProcessor，包含一个 CreateInstance 函数。其目的在于，IProcessor 接口定义出每一个 Processor 都要执行的操作，而 IProcessorInstance 则是为了让 ProcessorFactory 能够简单的创建出&amp;ldquo;处理器&amp;rdquo;。&lt;/p&gt;&lt;p&gt;从 IProcessor 来理解，就非常简单、直观了。比如 CopyFileProcessor，和脚本中的&amp;ldquo;CopyFile | 源文件 | 目标文件 | [是否覆盖 = true]&amp;rdquo;相对应，所以，它包含三个属性：SourceFileName、TargetFileName 和 OverWrite。在它的构造函数中，根据传入的参数字符串数组，分析出那三个属性各自应该是什么，如果参数有错误，则抛出异常，而在 DoProcess 函数中，根据这三个参数，执行文件复制工作。&lt;/p&gt;&lt;p&gt;其它的 Processor 都大同小异，不过，比较特殊的是 CallScriptProcessor。这一个 Processor 的特殊之处在于，它要读出整个脚本，并通过 ProcessorFactory 创建出相应的 Processor，并且插入它的 _ProcessorList 集合这个属性之中。在 DoProcess 函数中，它执行一个简单的遍历，顺序执行 _ProcessorList 集合中所有的 Processor 的 DoProcess 函数。&lt;/p&gt;&lt;p&gt;所以，在程序运行后，首先创建出一个 CallScriptProcessor，它的 _ProcessorList 集合包含所有这个脚本中的 Processor，而如果这些 Processor 中又有 CallScriptProcessor，则这个 CallScriptProcessor 的 _ProcessorList 又包含子脚本中的 Processor，形成一个树结构，顺序遍历这颗树，并且执行其中的 DoProcess 函数，就会执行整个脚本链。这样，每一个 Processor 各司其职，把它们整合在一起后就正确的执行并得到了我们希望的结果。&lt;/p&gt;&lt;p&gt;ProcessorFactory 包含一个 CreateProcessorByScriptLine 函数，它通过一个脚本行创建一个相应的 Processor。这个函数对这个脚本行用&amp;ldquo;|&amp;rdquo;分割，根据分割后的字符串数组的第一个字符串，决定创建哪一个 Processor。这个创建的过程被通过 IProcessorInstance 接口的 CreateInstance 函数分配给了各个 Processor，所以 CreateInstance 应该使用 new 来产生一个自己的实例。&lt;/p&gt;&lt;p&gt;比较特殊的一点是，各个 Processor 的带参数的构造函数的访问符都是 private，这是为了防止在复制其它 Processor 代码以创建新的 Processor 的时候，忘了修改 CreateInstance 而造成错误。当其访问符是 private 的时候，如果忘了修改 CreateInstance 的话，将会产生一个编译错误，提醒我们应该修改它。&lt;/p&gt;&lt;p&gt;在 ProcessorFactory 初始化的时候，通过一个 Hashtable 把脚本命令和 Processor 形成一一对应的关系，在 CreateProcessorByScriptLine 中就只要使用这个 Hashtable 就可以创建 Processor，而不必使用冗长而不易维护的 switch 语句了。&lt;/p&gt;&lt;p&gt;而在第二版中，主要是增加了自定义属性 ActiveProcessorAttribute，它接受一个字符串作为 Processor 对应的脚本命令名。而在 ProcessorFactory 中，使用反射取得这个模块中所有的类，并且检查，如果某一个类是从 IProcessor 接口继承，而且定义了 ActiveProcessorAttribute 属性的话，就会被加入 Hashtable，而在 CreateProcessorByScriptLine，通过反射找到这个类的构造函数，并且使用 Invoke 调用这个构造函数，完成 Processor 的创建。这样，ProcessorFactory 在增加新的 Processor 的情况下，不需要有任何修改，而 Processor 本身，也消除了对于 CreateInstance 和无参数的构造函数的需求，变得更加简单、清晰，而 IProcessorInstance 接口也不需要了。。&lt;/p&gt;&lt;p&gt;为什么说这种方法比直观的代码编写方法好呢？我们来看看一个直观的代码是怎么解决这个问题，并且对应于代码的演化，直观的代码和这种使用一个统一的接口的方式之间的差别。&lt;/p&gt;&lt;p&gt;从直观的角度讲，我们的程序应该读取这个脚本，并且执行相应的操作，一个 switch 结构应该是第一个对于此类实现的想法：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ApplicationEntry&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Main(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; [] args)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( args &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; args.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;        {&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( FileStream f &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream(args[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;]) )&lt;br /&gt;            {&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; s;&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( (s &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; f.ReadLine()) &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                {&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( s.Trim() &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                    {&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss[] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s.Split(&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;|&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( ss &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                        {&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt;( ss[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToLower() )&lt;br /&gt;                            {&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt;: &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 是注释&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;                                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;copyfile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                    DoCopyFile(ss);&lt;br /&gt;                                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;deletefile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                    DoDeleteFile(ss);&lt;br /&gt;                                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/p&gt;&lt;p&gt;以上代码中没有展示 DoCopyFile 之类的函数，这些函数需要在内部解析 ss，并且执行相应的操作，在只有简单的操作，而且只有少量的指令的时候也还算可以理解，不过，增加了 CallScript 之后，就有些困难，需要进行重构了：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ApplicationEntry&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Main(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; [] args)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( args &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; args.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;        {&lt;br /&gt;            ProcessFile(args[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;]);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ProcessFile(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileName)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( FileStream f &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream(FileName) )&lt;br /&gt;        {&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; s;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( (s &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; f.ReadLine()) &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;            {&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( s.Trim() &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                {&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss[] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s.Split(&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;|&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( ss &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                    {&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt;( ss[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToLower() )&lt;br /&gt;                        {&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt;: &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 是注释&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;copyfile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                DoCopyFile(ss);&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;deletefile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                DoDeleteFile(ss);&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;callscript&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                DoCallScript(ss);&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    DoCallScript(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] ss)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( ss.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;        {&lt;br /&gt;            ProcessFile(ss[&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;这样，这种 switch 结构使用递归调用的方法，虽然有些结构混乱，也实现了 CallScript。不过，在设计 SimpleScript 引擎的时候，有对于 Script 中的参数错误的提示的要求：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2010/83760/2010122313275234.gif" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一开始，我是把 CallScript 的 ReadToEnd( _TargetFileName ) 放在 DoProcess() 函数中的，这样，如果当前脚本出错，就会出现错误提示：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; DoProcess()&lt;br /&gt;{&lt;br /&gt;    ReadToEnd( _TargetFileName );&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( IProcessor ip &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; _ProcessorList )&lt;br /&gt;    {&lt;br /&gt;        ip.DoProcess();&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;不过，后来我觉得，这种脚本错误是应该在执行任何一个指令前进行的检查，即使对于子脚本中的错误，也应该在所有脚本执行之前提示，所以修改代码，把 ReadToEnd( _TargetFileName ) 移动到 CallScript 的构造函数中，就完成了这个任务：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; CallScriptProcessor(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; [] Params)&lt;br /&gt;{&lt;br /&gt;    _ProcessorList &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Collections.ArrayList();&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt;( Params.Length )&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            _TargetFileName &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; IOHelper.GetFullPath( Params[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;] );&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ParseParamErrorException();&lt;br /&gt;    }&lt;br /&gt;    ReadToEnd( _TargetFileName );&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;现在，我们来考虑一下上面的 switch 结构的程序要实现这种类型的脚本错误检查的话，需要进行哪些修改呢？因为在 switch 结构的程序中，脚本行的解析和执行是在同一个地方进行的，所以首先应该把它们进行拆分，不过，如果把 DoCopyFile 拆分成两个函数，那么解析函数解析出的参数怎么传递给执行函数？也许应该建立一个 CopyFile_SourceFile 和 CopyFile_TargetFile 吧。抛开参数传递的问题，如果已经把以前的 DoCopyFile 函数都拆分成了解析函数和执行函数两部分，为了实现执行前脚本参数检查，应该怎么修改程序的结构呢？恐怕还是需要一个解析用的 switch 语句组吧：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ProcessScriptParam(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileName)&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( FileStream f &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream(FileName) )&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; s;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( (s &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; f.ReadLine()) &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;        {&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( s.Trim() &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;            {&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss[] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s.Split(&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;|&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( ss &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                {&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt;( ss[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToLower() )&lt;br /&gt;                    {&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt;: &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 是注释&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;copyfile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            ParseCopyFileParam(ss);&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;deletefile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            ParseDoDeleteFileParam(ss);&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;callscript&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            ParseDoCallScriptParam(ss);&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ProcessFile(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileName)&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( FileStream f &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream(FileName) )&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; s;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( (s &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; f.ReadLine()) &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;        {&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( s.Trim() &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;            {&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss[] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s.Split(&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;|&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( ss &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                {&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt;( ss[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToLower() )&lt;br /&gt;                    {&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt;: &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 是注释&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;copyfile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            ParseCopyFileParam(ss);&lt;br /&gt;                            ProcessCopyFile(ss);&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;deletefile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            ParseDoDeleteFileParam(ss);&lt;br /&gt;                            ProcessDeleteFile(ss);&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;callscript&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            ParseDoCallScriptParam(ss);&lt;br /&gt;                            ProcessCallScript(ss);&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;现在，switch 结构的程序已经变成了这种庞大而难于维护的样子，如果要增加一个新的操作，就更加困难了，除了要实现相应的解析执行函数之外，还要维护这两个庞大的 switch 结构，出错的可能性也大大增加了。而相对的，我写的 SimpleScript 的代码，任何时候新增一个操作，都是同样的简单&amp;hellip;&amp;hellip;&lt;/p&gt;&lt;p&gt;当然，对于 Processor 的结构来说，我使用的是命令（Command）模式，而对于 Processor 的创建来说，我使用的是原型（Prototype）模式。不过，在设计中，我并没有，其实也不太清楚我使用了哪种模式，只是在多种想法中进行选择，对代码进行重构，最终得到了我认为最好的结构 &amp;mdash;&amp;mdash; 而这种结构正好符合了某些设计模式。现在看来，反而是这种自行发现模式的情况，更有利于对于设计模式有更深的认识。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;源代码下载：&lt;/p&gt;&lt;p&gt;&lt;a href="http://llf.hanzify.org/studio/article/show/326" target="_blank"&gt;点睛简单脚本引擎 第一版&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://llf.hanzify.org/studio/article/show/328" target="_blank"&gt;点睛简单脚本引擎 第二版&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/1914751.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2010/12/23/analyze_simple_script_engine.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/11/19/a_database_optimize_operation.html</id><title type="text">数据库操作优化一例</title><summary type="text">数据库升级，需要对几个表进行一些数据转换，具体是这样：针对每一个 Item，从 orders 表里查出 Shop_Id，并把此 Id 赋值给 items 和 skus 中的 Shop_Id。下面是最初实现的代码，其中 LargerResultProcessor 是一个基类，负责遍历泛型参数 T 所指向的数据库表，并以每页 100 项的方式分页，并对每一项调用 ProcessItem 函数，而子类只...</summary><published>2010-11-19T07:23:00Z</published><updated>2010-11-19T07:23:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/11/19/a_database_optimize_operation.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/11/19/a_database_optimize_operation.html"/><content type="html">&lt;p&gt;数据库升级，需要对几个表进行一些数据转换，具体是这样：针对每一个 Item，从 orders 表里查出 Shop_Id，并把此 Id 赋值给 items 和 skus 中的 Shop_Id。下面是最初实现的代码，其中 LargerResultProcessor 是一个基类，负责遍历泛型参数 T 所指向的数据库表，并以每页 100 项的方式分页，并对每一项调用 ProcessItem 函数，而子类只需实现 ProcessItem 函数即可：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('17aead26-1ed2-42ba-9c53-425b1d61353a')"&gt;&lt;div id="cnblogs_code_open_17aead26-1ed2-42ba-9c53-425b1d61353a"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ItemRenameCompanyId : LargerResultProcessor&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Item&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ProcessItem(Item item)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; template1 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;select top 1 shop_id from orders where Item_id = '{0}'&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;        var sql1 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Format(template1, item.Id);&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; template2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;update Items set shop_id={0} where id = {1};&lt;br /&gt;                                   update skus set shop_id={0} where item_id = {1};&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        {&lt;br /&gt;            var obj &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; DbEntry.Context.ExecuteScalar(sql1);&lt;br /&gt;            var sql2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Format(template2, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;long&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Parse(obj.ToString()), item.Id);&lt;br /&gt;            DbEntry.Context.ExecuteNonQuery(sql2);&lt;br /&gt;        }&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Exception exception)&lt;br /&gt;        {&lt;br /&gt;            Logger.Default.Warn(exception &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; item.Id.ToString());&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;上面这段代码，逻辑比较简单，针对每一项，使用 Select 语句取出 Shop_Id，并且执行 Update，只是有个问题，就是执行速度比较慢，对于我们 6 万左右 Item，4 万左右 Sku，99 万左右 Order 的表，需要执行约 40 分钟，才能转换完毕。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这些代码，虽然是一次性操作，但是对于运行系统，停机时间越短越好，于是进行一些优化工作，数据库对于大量重复的语句，如果使用参数的方式，因为可以避免对于语句的重复解析工作，所以速度会快一些，按照这个思路，简单的修改如下：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('aa59287f-379b-4717-8dab-e0d3d34304fd')"&gt;&lt;div id="cnblogs_code_open_aa59287f-379b-4717-8dab-e0d3d34304fd"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ItemRenameCompanyId : LargerResultProcessor&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Item&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ProcessItem(Item item)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; template1 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;select top 1 shop_id from orders where Item_id = @id&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; template2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;update Items set shop_id=@sid where id = @id;&lt;br /&gt;update skus set shop_id=@sid where item_id = @id;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        {&lt;br /&gt;            var sql1 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; SqlStatement(template1, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DataParameter(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;@id&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, item.Id));&lt;br /&gt;            var sid &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Convert.ToInt64(DbEntry.Context.ExecuteScalar(sql1));&lt;br /&gt;            var sql2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; SqlStatement(template2, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DataParameter(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;@sid&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, sid), &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DataParameter(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;@id&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, item.Id));&lt;br /&gt;            DbEntry.Context.ExecuteNonQuery(sql2);&lt;br /&gt;        }&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Exception exception)&lt;br /&gt;        {&lt;br /&gt;            Logger.Default.Warn(exception &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; item.Id.ToString());&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;测试这个程序，大概 25 分钟可以完成转换。有一些提高，不过，我们真正要修改的数据量并不大，一共只有 6 万 加 4 万 大约 10 万条数据，所以 25 分钟还是有些长了。简单分析后，Orders 是最大的表，如果整体速度慢，则导致速度慢最大的可能因素，应该是查询 Orders，所以稍换一个思路，提前把 Item_Id 和 Shop_Id 的对应关系查找出来，放到内存里，从而避免每次 ProcessItem 都要进行 Orders 表的查询。至于内存里的数据，本来准备用 Dictionary 的，后来一想，Id 都是 long 型的数据，而且不能算&amp;ldquo;稀疏&amp;rdquo;矩阵，基本可以称为&amp;ldquo;稠密&amp;rdquo;矩阵，所以，直接用数组应该是速度更快，所以先查询出 Items 的最大 Id，用于设置数组大小，再按索引赋值即可：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('a9281afe-4a56-4d9d-aa02-8866cacfa7b3')"&gt;&lt;div id="cnblogs_code_open_a9281afe-4a56-4d9d-aa02-8866cacfa7b3"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ItemRenameCompanyId : LargerResultProcessor&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Item&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;long&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] _dic;&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; ItemRenameCompanyId()&lt;br /&gt;    {&lt;br /&gt;        var count &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Convert.ToInt64(DbEntry.Context.ExecuteScalar(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;select top 1 Id from items order by id desc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;)) &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;br /&gt;        _dic &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;long&lt;/span&gt;&lt;span style="color: #000000;"&gt;[count];&lt;br /&gt;&lt;br /&gt;        var sql &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; SqlStatement(&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;select items.id as xiid,orders.shop_id as xsid from items inner join orders on orders.item_id = items.id group by items.id,orders.shop_id&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;                {SqlTimeOut &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;300&lt;/span&gt;&lt;span style="color: #000000;"&gt;};&lt;br /&gt;&lt;br /&gt;        dynamic list &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; DbEntry.Context.ExecuteDynamicList(sql);&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt;(dynamic row &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; list)&lt;br /&gt;        {&lt;br /&gt;            _dic[row.xiid] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; row.xsid;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ProcessItem(Item item)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; template2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;update Items set shop_id=@sid where id = @id;&lt;br /&gt;update skus set shop_id=@sid where item_id = @id;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        {&lt;br /&gt;            var sid &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; _dic[item.Id];&lt;br /&gt;            var sql2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; SqlStatement(template2, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DataParameter(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;@sid&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, sid), &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DataParameter(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;@id&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, item.Id));&lt;br /&gt;            DbEntry.Context.ExecuteNonQuery(sql2);&lt;br /&gt;        }&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Exception exception)&lt;br /&gt;        {&lt;br /&gt;            Logger.Default.Warn(exception &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; item.Id.ToString());&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;再测试这一段程序，运行 70 秒就完成了数据转换，另外，查询对应关系那一句 SQL，因为针对的是刚恢复的数据库，所以用了大概 3、40 秒，实际使用查询管理器，在运行中的数据库执行那一句 SQL，只需要 1 秒左右就可以完成，所以，估计在实际转换的时候，3、40 秒就可以完成转换了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/1881840.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2010/11/19/a_database_optimize_operation.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/07/05/using_cecil_to_modify_assembly.html</id><title type="text">使用 Cecil 修改 .Net 程序集</title><summary type="text">Cecil 是 Mono 的一个子项目，用于对程序集进行读写，并且已经用于 Mono 的调试，Reflector 也使用它作为底层库。最近把 DbEntry 使用 Emit 生成程序集的方式，改成了使用 Cecil 的方式，就我的感受来说，Cecil 是比较优秀的，有一些地方，比 Emit 使用起来还舒服的多；不过，有一些地方也比较繁琐。我使用的是 Git 里的最新版本，如果大家要测试的话，也...</summary><published>2010-07-05T13:45:00Z</published><updated>2010-07-05T13:45:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/07/05/using_cecil_to_modify_assembly.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/07/05/using_cecil_to_modify_assembly.html"/><content type="html">&lt;p&gt;Cecil 是 Mono 的一个子项目，用于对程序集进行读写，并且已经用于 Mono 的调试，Reflector 也使用它作为底层库。最近把 &lt;a href="http://dbentry.codeplex.com"&gt;DbEntry&lt;/a&gt; 使用 Emit 生成程序集的方式，改成了使用 Cecil 的方式，就我的感受来说，Cecil 是比较优秀的，有一些地方，比 Emit 使用起来还舒服的多；不过，有一些地方也比较繁琐。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;我使用的是 Git 里的最新版本，如果大家要测试的话，也建议使用 Git 版，所以，需要安装一个 Git 客户端。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这里，用一个非常简单的例子，说明一下 Cecil 的基本用法。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;首先，我们编写一个测试用的程序集 TestApp.exe :&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt; TestApp&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Main()&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Main&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Before()&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Before&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; After()&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;After&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;然后，编写一个使用 Cecil 进行改写的应用 CecilTest.exe :&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Linq;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Mono.Cecil;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Mono.Cecil.Cil;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt; CecilTest&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Main(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] args)&lt;br /&gt;        {&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(args.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Usage: CecilTest TestApp.exe&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            var m &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; ModuleDefinition.ReadModule(args[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;]);&lt;br /&gt;&lt;br /&gt;            var prog &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; m.Types.First(p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; p.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Program&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;            var main &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; prog.Methods.First(p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; p.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Main&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;            var before &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; prog.Methods.First(p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; p.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Before&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;            var after &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; prog.Methods.First(p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; p.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;After&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;br /&gt;            var il &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; main.Body.GetILProcessor();&lt;br /&gt;            il.InsertBefore(main.Body.Instructions[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;], il.Create(OpCodes.Call, before));&lt;br /&gt;            il.InsertBefore(main.Body.Instructions.Last(), il.Create(OpCodes.Call, after));&lt;br /&gt;&lt;br /&gt;            m.Write(args[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;] &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;.exe&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;br /&gt;            Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Done&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;编译这两个项目，并且使用 CecilTest.exe 处理一下 TestApp.exe，生成 TestApp.exe.exe，运行 TestApp.exe，运行结果：&lt;br /&gt;Main&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;运行 TestApp.exe.exe，运行结果：&lt;/p&gt;&lt;p&gt;Before&lt;br /&gt;Main&lt;br /&gt;After&lt;br /&gt;&lt;br /&gt;可以看到，我们已经成功的在 Main 函数的前后，分别插入了一次函数调用。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;基本使用方法就是这样，大体和 Emit 类似，只是不止可以使用 Emit 函数，还可以直接修改程序集。当然，还有其它一些细节的不同，比如它的变量定义不是通过 ILProcessor，而是直接操作函数体的 Variables；再比如它没有 DeclareLabel 函数，跳转直接引用函数体的 Instruction 进行。另外，它可以只加载目标程序集，却不加载其依赖项，所以很多东西都分定义和引用两种。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;就目前来说，我认为它的效果是令人满意的。不过它最大的问题，在于泛型处理上。不是说不能做，而是太繁琐，有时候甚至是不可能。在 DbEntry 中，最后被泛型击败，采取了 Reflection+Cecil 的方式，这种方式简单易行，不过问题是，Reflection 需要加载程序集，除了可能出现无法加载依赖项的异常外，也无法简单的回写原文件。我在 Cecil 的 Git 上提交了 issue，不过作者回复，不觉得这是问题，所以我也懒得纠缠了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/1771697.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2010/07/05/using_cecil_to_modify_assembly.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/05/24/csharp_gpgpu_with_opencl.html</id><title type="text">使用 OpenCL.Net 进行 C# GPU 并行编程</title><summary type="text">在 初探 C# GPU 通用计算技术 中，我使用 Accelerator 编写了一个简单的 GPU 计算程序。也简单看了一些 Brahma 的代码，从它的 SVN 最新代码看，Brahma 要转移到使用 OpenCL.Net 作为底层了，于是也去网上搜索了一下，发现了 OpenCL.Net 和另一个相关的项目 OpenCLTemplate。看了一些它的代码，颇像 DirectCompute 的风格...</summary><published>2010-05-24T12:47:00Z</published><updated>2010-05-24T12:47:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/05/24/csharp_gpgpu_with_opencl.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/05/24/csharp_gpgpu_with_opencl.html"/><content type="text">在 初探 C# GPU 通用计算技术 中，我使用 Accelerator 编写了一个简单的 GPU 计算程序。也简单看了一些 Brahma 的代码，从它的 SVN 最新代码看，Brahma 要转移到使用 OpenCL.Net 作为底层了，于是也去网上搜索了一下，发现了 OpenCL.Net 和另一个相关的项目 OpenCLTemplate。看了一些它的代码，颇像 DirectCompute 的风格...</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/05/23/csharp_gpgpu.html</id><title type="text">初探 C# GPU 通用计算技术</title><summary type="text">GPU 的并行计算能力高于 CPU，所以最近也有很多利用 GPU 的项目出现在我们的视野中，在 InfoQ 上看到这篇介绍 Accelerator-V2 的文章，它是微软研究院的研究项目，需要注册后才能下载，感觉作为我接触 GPU 通用运算的第一步还不错，于是去下载了回来。在安装包里，包含了几个例子程序，比如著名的 Life 游戏，不过，Life 游戏，相对于刚接触 GPU 运算的我，还是稍显复杂...</summary><published>2010-05-23T11:02:00Z</published><updated>2010-05-23T11:02:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/05/23/csharp_gpgpu.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/05/23/csharp_gpgpu.html"/><content type="text">GPU 的并行计算能力高于 CPU，所以最近也有很多利用 GPU 的项目出现在我们的视野中，在 InfoQ 上看到这篇介绍 Accelerator-V2 的文章，它是微软研究院的研究项目，需要注册后才能下载，感觉作为我接触 GPU 通用运算的第一步还不错，于是去下载了回来。在安装包里，包含了几个例子程序，比如著名的 Life 游戏，不过，Life 游戏，相对于刚接触 GPU 运算的我，还是稍显复杂...</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/05/15/think_of_design_pattern.html</id><title type="text">我的设计模式观</title><summary type="text">设计模式是有效的架构设计方法，甚至可以说是面向对象编程的范例，不过，学习设计模式比学习一种同类型的语言（比如Java之于C#）困难得多。简历中不少人会或多或少提到设计模式，但是真的问时，大多又是只能说出“工厂”，“单例”之类的模式，这些模式是比较简单，同时也是重要的模式，不过，创建型模式更像味精，用于调味其它的结构性模式，脱离了结构性模式，创建型模式...</summary><published>2010-05-15T01:10:00Z</published><updated>2010-05-15T01:10:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/05/15/think_of_design_pattern.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/05/15/think_of_design_pattern.html"/><content type="text">设计模式是有效的架构设计方法，甚至可以说是面向对象编程的范例，不过，学习设计模式比学习一种同类型的语言（比如Java之于C#）困难得多。简历中不少人会或多或少提到设计模式，但是真的问时，大多又是只能说出“工厂”，“单例”之类的模式，这些模式是比较简单，同时也是重要的模式，不过，创建型模式更像味精，用于调味其它的结构性模式，脱离了结构性模式，创建型模式...</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/04/24/serialization_speed_test.html</id><title type="text">有关于序列化速度的测试</title><summary type="text">项目里数据库表有很多字段，而且有不少字段不确定长度，所以决定，把大多数不常用字段用 XML 序列化的方式，保存到一个字段内，不过却发现，从网上取一条 10K 左右的 XML 数据，反序列化，解析、转义，然后分别设置到4、5个对象中，这些对象，再对自身的不常用字段进行 XML 序列化，然后保存对象到数据库，竟然要花 5 秒左右的时间。下载了一个 DotTrace + TestDriven.Net...</summary><published>2010-04-24T05:27:00Z</published><updated>2010-04-24T05:27:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/04/24/serialization_speed_test.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/04/24/serialization_speed_test.html"/><content type="text">项目里数据库表有很多字段，而且有不少字段不确定长度，所以决定，把大多数不常用字段用 XML 序列化的方式，保存到一个字段内，不过却发现，从网上取一条 10K 左右的 XML 数据，反序列化，解析、转义，然后分别设置到4、5个对象中，这些对象，再对自身的不常用字段进行 XML 序列化，然后保存对象到数据库，竟然要花 5 秒左右的时间。下载了一个 DotTrace + TestDriven.Net...</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/04/17/dbentry3_9.html</id><title type="text">DbEntry.Net 3.9</title><summary type="text">这是我设计的一个轻量级的 .Net ORM (Object Relational Mapping) 数据访问及 WEB 框架。对于 ORM 和 Sql 调用，它都拥有清晰和易用的接口，目前支持 SqlServer、SQLite、MySql、Access、Firebird、PostgreSQL、Oracle 等数据库。对于 WEB 开发，它既支持 ASP.NET 2.0 的 DataSource 方...</summary><published>2010-04-17T08:42:00Z</published><updated>2010-04-17T08:42:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/04/17/dbentry3_9.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/04/17/dbentry3_9.html"/><content type="text">这是我设计的一个轻量级的 .Net ORM (Object Relational Mapping) 数据访问及 WEB 框架。对于 ORM 和 Sql 调用，它都拥有清晰和易用的接口，目前支持 SqlServer、SQLite、MySql、Access、Firebird、PostgreSQL、Oracle 等数据库。对于 WEB 开发，它既支持 ASP.NET 2.0 的 DataSource 方...</content></entry></feed>
