﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-251</title><link>http://www.cnblogs.com/itrust/</link><description>纷繁错杂的社会在地震中简单化,冷漠物化的心灵在灾难中温情化。亦喜亦忧，能保持多久？</description><language>zh-cn</language><lastBuildDate>Fri, 05 Sep 2008 18:23:11 GMT</lastBuildDate><pubDate>Fri, 05 Sep 2008 18:23:11 GMT</pubDate><ttl>60</ttl><item><title>仍有人在真心关注这灾难</title><link>http://www.cnblogs.com/itrust/archive/2008/07/29/1256028.html</link><dc:creator>251</dc:creator><author>251</author><pubDate>Tue, 29 Jul 2008 15:54:00 GMT</pubDate><guid>http://www.cnblogs.com/itrust/archive/2008/07/29/1256028.html</guid><wfw:comment>http://www.cnblogs.com/itrust/comments/1256028.html</wfw:comment><comments>http://www.cnblogs.com/itrust/archive/2008/07/29/1256028.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/itrust/comments/commentRss/1256028.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/itrust/services/trackbacks/1256028.html</trackback:ping><description><![CDATA[<p><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;地震的尘烟已然被奥运的烟火盖掉，大众的眼球从废墟转向鸟巢。人们的生活进入了一个新的阶段，幸福的人们继续享受幸福，悲伤的人们逐渐忘却悲伤，困苦的人们开始努力创建新的生活。</span>&nbsp;</p>
<p><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在经历地震的日子里，我曾同朋友（一个脚板不触及地面的超凡脱俗的女子）争辩一个问题&#8220;有多少人真心关注这灾难？&#8221;。我们达成一致: 是这样的人，再过两三个月，还能主动提及这灾难，主动帮助受灾的人们。基于这结论，朋友很悲观，因大多数人的猎奇心态而哀叹。说实话，我也认为这样的人很少。但是不能够因此在道义层面对人们做出评判。对于个体而言，一个事件所能激发的关注度取决于其体验和记忆与这事件的关联度。我们没有在家乡亲身经历这灾难，但感同身受，夜不能眠，是因为电视里、报纸上、网络中不断闪现的是自己熟悉的地名、人名，甚而面孔。他们的每一次出现，都会唤起一份记忆或是一次体验，刺激一次神经。如果没有这些关联的记忆和体验，你甚至没有去过这些地方，没有听说这地名，那刺激只能来源于那些平时难得一见的画面。在年初雪灾中，我们都没有捐款，忘却的也很快。</span>&nbsp;</p>
<p><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我很兴奋，午夜来敲入这段文字，是因为我的朋友中有这样的人: 时隔两三月，仍关切这灾难，且慷慨相助。虽然当时在MSN上有很多朋友激情加入，但在推进一加一的时候我很仍很惶恐，担忧这援助活动给朋友带来道德和信义的考验，我谨慎的选择在地震一个月后还主动询问的朋友。经历过一些尴尬，沙去金现，今夜，又有两个孩子得到了三年的学费援助。我相信，所有参与的人们是快乐的。我，尤其快乐！因为我有过几乎失去教育机会的体验，因为这些优秀的孩子很有可能因此而改变人生的轨迹，更是因为我交到了这些值得交往的朋友，他们甚至和这事件没有太多的关联度。快哉！乐哉！</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<img src ="http://www.cnblogs.com/itrust/aggbug/1256028.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42116/" target="_blank">[新闻]消息称MySQL创始人已向Sun提交辞呈</a>]]></description></item><item><title>CruiseControl中应用NCover和NCoverExplore</title><link>http://www.cnblogs.com/itrust/archive/2008/07/22/1248487.html</link><dc:creator>251</dc:creator><author>251</author><pubDate>Tue, 22 Jul 2008 02:18:00 GMT</pubDate><guid>http://www.cnblogs.com/itrust/archive/2008/07/22/1248487.html</guid><wfw:comment>http://www.cnblogs.com/itrust/comments/1248487.html</wfw:comment><comments>http://www.cnblogs.com/itrust/archive/2008/07/22/1248487.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/itrust/comments/commentRss/1248487.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/itrust/services/trackbacks/1248487.html</trackback:ping><description><![CDATA[<p>曾经想在CruiseControl.Net上加入NCover和NCoverExplorer来输出测试案例覆盖代码的情况，当时因在Ncover.org上发现要$而作罢。</p>
<p>偶然获知其老版依然免费，心里痒痒，再次尝试。感觉CC的帮助写得不够完善，就来涂一篇。</p>
<p>&nbsp;</p>
<p><strong>配置CC项目</strong></p>
<p>1 通过NCover调用NUnit做测试，就不需要在项目中其他地方再做一次了。NCover将在baseDirectory中生成Coverage.xml文件。</p>
<div class="cnblogs_code" style="width: 908px; height: 79px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><strong><img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">exec&nbsp;</span><span style="color: #ff0000">executable</span><span style="color: #0000ff">="D:\Studio\tools\NCover\NCover.console.exe"</span></strong><strong><span style="color: #ff0000">&nbsp;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;baseDirectory</span><span style="color: #0000ff">="D:\studio\"</span></strong><strong><span style="color: #ff0000">&nbsp;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buildArgs</span><span style="color: #0000ff">="D:\Studio\tools\nunit\nunit-console.exe&nbsp;/noshadow&nbsp;D:\studio\tests\bin\Release\MyTest.dll&nbsp;/xml:D:\studio\nunit-results.xml"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span></strong></div>
<p>&nbsp;</p>
<p>2 接下来基于Coverage.xml生成NCoverExplore报告(CoverageReport.xml)：</p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">exec&nbsp;</span><span style="color: #ff0000">executable</span><span style="color: #0000ff">="D:\Studio\tools\NCover\NCoverExplorer.Console.exe"</span><span style="color: #ff0000">&nbsp;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;baseDirectory</span><span style="color: #0000ff">="D:\studio\"</span><span style="color: #ff0000">&nbsp;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buildArgs</span><span style="color: #0000ff">="/x&nbsp;/r:4"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">tasks</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span></div>
<p>&nbsp;</p>
<p>3 将NUnit、NCover和NCoverExplore的输出文件合并到本次集成的日志中（注意: merge节必须放在xmllogger之前）：</p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">publishers</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">merge</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">files</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">file</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">D:\studio\nunit-results.xml</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">file</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">file</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">D:\studio\Coverage.xml</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">file</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">file</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">D:\studio\CoverageReport.xml</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">file</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">files</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">merge</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xmllogger&nbsp;</span><span style="color: #ff0000">logDir</span><span style="color: #0000ff">="log"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">publishers</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></div>
<p>&nbsp;</p>
<p><strong>配置Web DashBoard</strong></p>
<p>1 在编译的总报告中加入<font style="color: red" color="#ff0000">NCoverSummary</font>和<font color="#ff0000">NCoverExplorerSummary</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&lt;buildReportBuildPlugin&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;xslFileNames&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xslFile&gt;xsl\header.xsl&lt;/xslFile&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xslFile&gt;xsl\modifications.xsl&lt;/xslFile&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xslFile&gt;xsl\compile.xsl&lt;/xslFile&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xslFile&gt;xsl\compile-msbuild.xsl&lt;/xslFile&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xslFile&gt;xsl\unittests.xsl&lt;/xslFile&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xslFile&gt;xsl\fxcop-summary.xsl&lt;/xslFile&gt;<br />
&nbsp;<span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&lt;xslFile&gt;xsl\NCoverSummary.xsl&lt;/xslFile&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xslFile&gt;xsl\NCoverExplorerSummary.xsl&lt;/xslFile&gt;<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xslFile&gt;xsl\SimianSummary.xsl&lt;/xslFile&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xslFileNames&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;/buildReportBuildPlugin&gt;&nbsp;&nbsp;</p>
<p>&nbsp; 其输出如图：</p>
<p align="center">
<div align="center"><img height="277" alt="" src="http://images.cnblogs.com/cnblogs_com/itrust/NCoverSummary.PNG" width="738" border="0" /></div>
<div align="left">&nbsp;</div>
<div align="left">2 加入详细报告NCover.xsl 和 NCoverExplore.xsl</div>
<p>&nbsp;</p>
<div align="left">&nbsp;&nbsp;&nbsp; &lt;xslReportBuildPlugin description="NCover Report" actionName="NCoverBuildReport" xslFileName="xsl\NCover.xsl" /&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;xslReportBuildPlugin description="NCover Explore" actionName="NCoverBuildExplore" xslFileName="xsl\NCoverExplorer.xsl" /&gt;</div>
<div align="left">&nbsp;&nbsp;&nbsp;&nbsp;NCover.xsl&nbsp;展示所有未调及的代码，其报告详细到代码行，爽！</div>
<div align="left">&nbsp;&nbsp;&nbsp; NCoverExplore.xsl展示一个直观的图形报告，如例：</div>
<div align="left">
<div align="center"><img height="403" alt="" src="http://images.cnblogs.com/cnblogs_com/itrust/NCoverExplore.PNG" width="685" border="0" /></div>
</div>
<div align="left">3 对了，别忘了重启IIS<br />
</div>
<div align="left"><strong>NCover的使用</strong></div>
<div align="left">* 只有编译出PDB符号文件的库，NCover才能检测</div>
<div align="left">* NCover排除测试案例： //ea NUnit.Framework.TestFixtureAttribute</div>
<img src ="http://www.cnblogs.com/itrust/aggbug/1248487.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42115/" target="_blank">[新闻]谷歌Chrome浏览器即将更换LOGO颜色？</a>]]></description></item><item><title>CruiseControl中使用NUnit中测试WEB服务</title><link>http://www.cnblogs.com/itrust/archive/2008/07/18/1246307.html</link><dc:creator>251</dc:creator><author>251</author><pubDate>Fri, 18 Jul 2008 11:44:00 GMT</pubDate><guid>http://www.cnblogs.com/itrust/archive/2008/07/18/1246307.html</guid><wfw:comment>http://www.cnblogs.com/itrust/comments/1246307.html</wfw:comment><comments>http://www.cnblogs.com/itrust/archive/2008/07/18/1246307.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/itrust/comments/commentRss/1246307.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/itrust/services/trackbacks/1246307.html</trackback:ping><description><![CDATA[摘要: 我的项目需要在CruiseControl中自动测试WEB服务，测试需满足下列条件：* 不依赖于IIS* 不对WebService做部署，直接在其CC编译的生成目录中运行WEB服务如果满足以上需求，当然也可以使用相同方式在VS和CC里测试网页。在网上找到了SCOTT的文章NUnit Unit Testing of ASP.NET Pages, Base Classes, Controls and o&nbsp;&nbsp;<a href='http://www.cnblogs.com/itrust/archive/2008/07/18/1246307.html'>阅读全文</a><img src ="http://www.cnblogs.com/itrust/aggbug/1246307.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42101/" target="_blank">[新闻]淘宝网合并阿里妈妈 专家称阿里巴巴或有新战略</a>]]></description></item><item><title>Resharper封装（Encapsulate)域Field为属性Property的命名问题</title><link>http://www.cnblogs.com/itrust/archive/2008/07/02/1234247.html</link><dc:creator>251</dc:creator><author>251</author><pubDate>Wed, 02 Jul 2008 11:13:00 GMT</pubDate><guid>http://www.cnblogs.com/itrust/archive/2008/07/02/1234247.html</guid><wfw:comment>http://www.cnblogs.com/itrust/comments/1234247.html</wfw:comment><comments>http://www.cnblogs.com/itrust/archive/2008/07/02/1234247.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/itrust/comments/commentRss/1234247.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/itrust/services/trackbacks/1234247.html</trackback:ping><description><![CDATA[一个讨厌的小问题，困扰了我一段时间，写上来，希望有同样问题而同样困扰的朋友能看到。<br />
<br />
我习惯于使用 _<em>name</em> 这样的格式来命名Field，但用Resharper3封装成属性时，没有像Resharper2那样给我建议命名为 <em>Name。<br />
</em><br />
解决方法，如此配置：<br />
在Options -&gt; Languages -&gt; Common -&gt; Naming Style 中 为Instance fields 的 Name Prefix中填入 "&nbsp;_ " 即可。<br />
<br />
如果你是这样命名 m_name, 则填入 " m_ " 即可。<br />
<br />
  <img src ="http://www.cnblogs.com/itrust/aggbug/1234247.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42096/" target="_blank">[新闻]微软研究院发布 AutoCollage - 整理并融合照片</a>]]></description></item><item><title>求才： .Net开发者（北京）</title><link>http://www.cnblogs.com/itrust/archive/2008/06/30/1232487.html</link><dc:creator>251</dc:creator><author>251</author><pubDate>Mon, 30 Jun 2008 06:54:00 GMT</pubDate><guid>http://www.cnblogs.com/itrust/archive/2008/06/30/1232487.html</guid><wfw:comment>http://www.cnblogs.com/itrust/comments/1232487.html</wfw:comment><comments>http://www.cnblogs.com/itrust/archive/2008/06/30/1232487.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnblogs.com/itrust/comments/commentRss/1232487.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/itrust/services/trackbacks/1232487.html</trackback:ping><description><![CDATA[我的团队一直致力于研发城市级网络视频监控报警系统，已经有一版程序应用在多个城市。<br />
公司的业务在发展，我们的系统也需要升级换代，因此需要更多的力量加入到团队里来，我们虚位以待！<br />
<br />
如果你<strong>真正关注自身技术能力的发展</strong>、<strong>喜欢做开发的工作</strong>，<strong>能够独立完成一个模块的工作</strong>，那么请联系我： <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#122;&#104;&#97;&#110;&#103;&#116;&#97;&#111;&#46;&#105;&#116;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">zhangtao.it@gmail.com</a><img src ="http://www.cnblogs.com/itrust/aggbug/1232487.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42100/" target="_blank">[新闻]2008年9月5日科技博客精选</a>]]></description></item><item><title>数据库开发的持续集成 - CruiseControl.Net的项目配置</title><link>http://www.cnblogs.com/itrust/archive/2008/06/25/1229902.html</link><dc:creator>251</dc:creator><author>251</author><pubDate>Wed, 25 Jun 2008 12:20:00 GMT</pubDate><guid>http://www.cnblogs.com/itrust/archive/2008/06/25/1229902.html</guid><wfw:comment>http://www.cnblogs.com/itrust/comments/1229902.html</wfw:comment><comments>http://www.cnblogs.com/itrust/archive/2008/06/25/1229902.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/itrust/comments/commentRss/1229902.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/itrust/services/trackbacks/1229902.html</trackback:ping><description><![CDATA[摘要: 本系列文章目录数据库开发的持续集成 - Sql Server 部署升级工具数据库开发的持续集成 - Sql Server数据库结构比较 数据库开发的持续集成 - 方法和流程 数据库开发的持续集成 - Liquibase的简介和应用 数据库的持续集成 - CruiseControl.Net的项目配置继续数据库的持续集成-方法和流程, 下面来说一下如何配置CruiseControl.Net的项目。流程&nbsp;&nbsp;<a href='http://www.cnblogs.com/itrust/archive/2008/06/25/1229902.html'>阅读全文</a><img src ="http://www.cnblogs.com/itrust/aggbug/1229902.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42099/" target="_blank">[新闻]SNS网站风靡影响工作效率 公司下令封杀</a>]]></description></item><item><title>数据库开发的持续集成 - Liquibase的简介和应用</title><link>http://www.cnblogs.com/itrust/archive/2008/06/20/1226374.html</link><dc:creator>251</dc:creator><author>251</author><pubDate>Fri, 20 Jun 2008 03:41:00 GMT</pubDate><guid>http://www.cnblogs.com/itrust/archive/2008/06/20/1226374.html</guid><wfw:comment>http://www.cnblogs.com/itrust/comments/1226374.html</wfw:comment><comments>http://www.cnblogs.com/itrust/archive/2008/06/20/1226374.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnblogs.com/itrust/comments/commentRss/1226374.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/itrust/services/trackbacks/1226374.html</trackback:ping><description><![CDATA[<p><span style="font-size: 10pt; font-family: 微软雅黑"><a title="数据库开发的持续集成 - Sql Server 部署升级工具" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html"><strong>本系列文章目录<br />
</strong><span style="font-size: 10pt; font-family: 微软雅黑">&nbsp;&nbsp;&nbsp;&nbsp;</a><a title="数据库开发的持续集成 - Sql Server 部署升级工具" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html">数据库开发的持续集成 - Sql Server 部署升级工具</a><a title="数据库开发的持续集成 - Sql Server 部署升级工具" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</a><a title="数据库开发的持续集成 - Sql Server数据库结构比较" href="http://www.cnblogs.com/itrust/archive/2008/06/05/1214156.html">数据库开发的持续集成 - Sql Server数据库结构比较</a><a title="数据库开发的持续集成 - Sql Server 部署升级工具" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html"><br />
&nbsp;&nbsp;&nbsp; </a><a class="entrylistItemTitle" id="CategoryEntryList1_EntryStoryList_Entries_ctl06_TitleUrl" href="http://www.cnblogs.com/itrust/archive/2008/06/17/1224141.html">数据库开发的持续集成 - 方法和流程</a><a title="数据库开发的持续集成 - Sql Server 部署升级工具" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html"><br />
&nbsp;&nbsp;&nbsp; </a><a class="entrylistItemTitle" id="CategoryEntryList1_EntryStoryList_Entries_ctl02_TitleUrl" href="http://www.cnblogs.com/itrust/archive/2008/06/20/1226374.html">数据库开发的持续集成 - Liquibase的简介和应用</a><a title="数据库开发的持续集成 - Sql Server 部署升级工具" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html"><br />
&nbsp;&nbsp;&nbsp; </a><a class="entrylistItemTitle" id="CategoryEntryList1_EntryStoryList_Entries_ctl00_TitleUrl" href="http://www.cnblogs.com/itrust/archive/2008/06/25/1229902.html">数据库的持续集成 - CruiseControl.Net的项目配置</a></span></span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; 在<a title="数据库开发的持续集成-方法和流程" href="http://www.cnblogs.com/itrust/archive/2008/06/17/1224141.html">数据库开发的持续集成-方法和流程</a>中，谈到了在持续集成中应用<a title="Liquibase" href="http://www.cnblogs.com/itrust/admin/www.Liquibase.org">Liquibase</a>，这里简单介绍一下，然后说说Liquibase在持续集成过程中的具体应用方法。<br />
<br />
<strong>Liquibase简介<br />
</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp; Liquibase是一个用于跟踪、管理和应用数据库变化的开源的数据库重构工具。它将所有数据库的变化（包括结构和数据）都保存在XML文件中，便于版本控制。<br />
&nbsp;&nbsp;&nbsp;&nbsp; Liquibase具备如下特性：<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 不依赖于特定的数据库，目前支持包括Oracle/Sql Server/DB2/MySql/Sybase/PostgreSQL/Cach&#233;等12种数据库，这样在数据库的部署和升级环节可帮助应用系统支持多数据库。<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 提供数据库比较功能，比较结果保存在XML中，基于该XML你可用Liquibase轻松部署或升级数据库。<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 以XML存储数据库变化，其中以作者和ID唯一标识一个变化（ChangSet），支持数据库变化的合并，因此支持多开发人员同时工作。<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 在数据库中保存数据库修改历史（DatabaseChangeHistory），在数据库升级时自动跳过已应用的变化（ChangSet）。<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 提供变化应用的回滚功能，可按时间、数量或标签（tag）回滚已应用的变化。通过这种方式，开发人员可轻易的还原数据库在任何时间点的状态。<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 可生成数据库修改文档（HTML格式）<br />
&nbsp;&nbsp;&nbsp;&nbsp; * 提供数据重构的独立的IDE和Eclipse插件<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Liquibase的核心就是存储变化的XML，如例：</p>
<div align="center">
<div class="cnblogs_code">
<div align="left"><img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">&lt;?</span><span style="color: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</span><span style="color: #0000ff">?&gt;</span><span style="color: #000000">&nbsp;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">databaseChangeLog<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;</span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://www.liquibase.org/xml/ns/dbchangelog/1.6"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;xmlns:xsi</span><span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;xsi:schemaLocation</span><span style="color: #0000ff">="http://www.liquibase.org/xml/ns/dbchangelog/1.6<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.6.xsd"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">changeSet&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="1"</span><span style="color: #ff0000">&nbsp;author</span><span style="color: #0000ff">="bob"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">createTable&nbsp;</span><span style="color: #ff0000">tableName</span><span style="color: #0000ff">="department"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">column&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="id"</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="int"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">constraints&nbsp;</span><span style="color: #ff0000">primaryKey</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000">&nbsp;nullable</span><span style="color: #0000ff">="false"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">column</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">column&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="name"</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="varchar(50)"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">constraints&nbsp;</span><span style="color: #ff0000">nullable</span><span style="color: #0000ff">="false"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">column</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">column&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="active"</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="boolean"</span><span style="color: #ff0000">&nbsp;defaultValue</span><span style="color: #0000ff">="1"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">createTable</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">changeSet</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">databaseChangeLog</span><span style="color: #0000ff">&gt;</span></div>
</div>
</div>
<div align="left"><br />
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其中，changeSet包含不同的数据库变化，<span style="color: red">几乎</span>涵盖了所有的数据库变化类型，具体支持的类型要看API，我这里给几个例子：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;创建和删除表、视图、存储过程、主键、外键、索引等<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 重命名表、视图、列等<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 加入列缺省值、唯一约束、非空约束等<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 合并两个列<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp; 在一个表的数据的基础上创建一个字典表<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;除此之外，Liquibase还允许你运行自己的Sql脚本、执行Shell程序。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 之所以所说&#8221;几乎涵盖&#8220;，是因为目前我发现不支持用户自定义数据和自定义函数的。由于在我新的数据库开发原则中摒弃了对他们的依赖，所以也不痛苦。<br />
<br />
<strong>Liquibase在持续集成中的应用<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong>如果你基于Java开发，你可能会更喜欢Liquibase，如果基于Ruby On Rails开发，你可能会选择Migration 和 Rake。我基于.Net，考察过Red Gate($),Migration.Net, <font face="Verdana">Machine.Migrations</font>,Power Tools等等，最终还是选择了Liquibase。如何整合到我的开发流程中来，我选择命令行以及基于命令行的MsBuild任务。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;用命令行搞一个bat文件执行Liquibase，用户数据库部署（见我例子中的deploy.bat)。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Msbuild提供比较、部署、文档生成等等全套功能，用于开发的全过程，当然也用于CC.Net（见例子中的ci.proj)。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;具体的应用包括：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 开发人员在本地完成一个阶段的开发后，使用ci.proj中的diff target比较本地数据和基线数据，产生changelog.xml，提交到SVN（这里，XML文件中的changeSet中的Author取开发人员本地机器的用户名）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * CC.Net检测到SVN的变化，触发持续集成过程，调用ci.proj中的deploy在一个测试数据库中创建最新的数据结构，然后对实体类和访问层进行测试（开发人员在本地机器的测试亦如此）。测试成功，使用ci.proj中的doc生成文档，发布在持续集成服务器的IIS中。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;如果是trunk项目则在测试完成后需要在SVN上打Tag，然后使用ci.proj中的publish发布数据库部署升级程序（含changelog.xml)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;发布的数据库部署升级程序中含deploy.bat给部署人员用以部署或升级现有的产品系统数据库。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;关于changelog.xml的合并：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 每一次开发人员有新的changelog.xml提交，我会通过SVN的Merge功能将其新的changeSet合并<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 这个过程可以通过SVN自动完成，但鉴于数据库的变化影响面太大，需要谨慎审核，因此还是选择手工来做<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 关于<font face="Verdana">test.proj： 这是用MsBuild写的一个测试案例，测试ci.proj提供的数据库比较和升级功能。</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;关于ci.proj的说明:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 对<font face="Verdana">dtproperties</font>的特殊处理<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一旦你使用过Sql Server的<font face="Verdana">企业管理器</font>操作过数据库，会自动生成这个表存一些数据库对象的属性。虽然在<font face="Verdana">企业管理器</font>中显示为系统表，但它的object_id很大，使得liquibase将其看做用户表，会影响数据库比较结果，因此在ci.proj中会检查参与比较的两个数据是否存在该表，如果不存在则创建它。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * <font face="Verdana">&lt;Target Name="CheckExec"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MsBuild使用Java命令行调用liquibase，如果执行出错，MsBuild不能得到该错误，这样将导致CC.Net的持续集成在失败时报成功。没有找到更好的办法，我将执行Java得到的输出写入exec.log文件，然后用CheckExec检查其中是否有Failed关键字。可能还有其他的关键字需要检查，如果园友发现还请告诉我。</font></p>
<div align="center">
<div class="cnblogs_code">
<div align="left"><img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">Target&nbsp;</span><span style="color: #ff0000">Name</span><span style="color: #0000ff">="CheckExec"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ReadLinesFromFile&nbsp;</span><span style="color: #ff0000">File</span><span style="color: #0000ff">="$(ExecLog)"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Output&nbsp;</span><span style="color: #ff0000">TaskParameter</span><span style="color: #0000ff">="Lines"</span><span style="color: #ff0000">&nbsp;PropertyName</span><span style="color: #0000ff">="ExecOutput"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ReadLinesFromFile</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Message&nbsp;</span><span style="color: #ff0000">Text</span><span style="color: #0000ff">="$(ExecOutput)"</span><span style="color: #ff0000">&nbsp;Importance</span><span style="color: #0000ff">="high"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">StringComparison&nbsp;</span><span style="color: #ff0000">Comparison</span><span style="color: #0000ff">="Contains"</span><span style="color: #ff0000">&nbsp;Param1</span><span style="color: #0000ff">="$(ExecOutput)"</span><span style="color: #ff0000">&nbsp;Param2</span><span style="color: #0000ff">="Failed"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Output&nbsp;</span><span style="color: #ff0000">TaskParameter</span><span style="color: #0000ff">="Result"</span><span style="color: #ff0000">&nbsp;PropertyName</span><span style="color: #0000ff">="StringSearchResult"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">StringComparison</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Delete&nbsp;</span><span style="color: #ff0000">Files</span><span style="color: #0000ff">="$(ExecLog)"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Error&nbsp;</span><span style="color: #ff0000">Text</span><span style="color: #0000ff">="liquibase&nbsp;report&nbsp;error"</span><span style="color: #ff0000">&nbsp;Condition</span><span style="color: #0000ff">="$(StringSearchResult)"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Target</span><span style="color: #0000ff">&gt;</span></div>
</div>
</div>
<div align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="Verdana"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;附件：<a title="持续集成项目文件" href="http://www.cnblogs.com/Files/itrust/db-ci-deploy.zip">持续集成项目文件</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><br />
&nbsp;&nbsp;&nbsp;<br />
<span style="color: red">Update20080718&nbsp;</span>&nbsp;发现Liquibase应用SQL Server生成修改记录的<a title="两个Bug" href="http://www.nabble.com/Drop-column-which-has-foreign-key-on-it-td18459767.html">两个Bug</a>：<br />
&nbsp;&nbsp;*&nbsp;删除一个定义了外键（引用其他表）的列时，删除Constraint的脚本放在了删列的脚本后面，导致部署失败<br />
&nbsp; * 添加NotNull的Constraint是，脚本中少了columnDataType,多了defaultNullValue，导致部署失败<br />
&nbsp;&nbsp;&nbsp;<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
<br />
</div>
 <img src ="http://www.cnblogs.com/itrust/aggbug/1226374.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42098/" target="_blank">[新闻]《孢子》正式发布</a>]]></description></item><item><title>Castle ActiveRecord笔记</title><link>http://www.cnblogs.com/itrust/archive/2008/06/17/1224190.html</link><dc:creator>251</dc:creator><author>251</author><pubDate>Tue, 17 Jun 2008 10:14:00 GMT</pubDate><guid>http://www.cnblogs.com/itrust/archive/2008/06/17/1224190.html</guid><wfw:comment>http://www.cnblogs.com/itrust/comments/1224190.html</wfw:comment><comments>http://www.cnblogs.com/itrust/archive/2008/06/17/1224190.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/itrust/comments/commentRss/1224190.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/itrust/services/trackbacks/1224190.html</trackback:ping><description><![CDATA[<p>&nbsp;选定使用Castle ActiveRecord开发数据库应用，感觉甚爽<img alt="" src="http://www.cnblogs.com/Emoticons/qface/055243485.gif" />，写个笔记，做点测试（<a title="源代码" href="http://www.cnblogs.com/Files/itrust/MyARTest.zip">源代码</a>）</p>
<h2>1 表列</h2>
<p style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">如果你的列名是数据库的保留字，在Property中用"`"声明列名</span><span style="font-size: 12pt; font-family: 宋体"> </p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">[Property(</span><span style="color: #800000">"</span><span style="color: #800000">`User`</span><span style="color: #800000">"</span><span style="color: #000000">)]<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;User<br />
<img id="Codehighlighter1_40_96_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_40_96_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_40_96_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_40_96_Closed_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_40_96_Closed_Image" style="display: none" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_40_96_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_40_96_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_40_96_Open_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_40_96_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_40_96_Open_Text"><span style="color: #000000">{<br />
<img id="Codehighlighter1_50_67_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_50_67_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_50_67_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_50_67_Closed_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_50_67_Closed_Image" style="display: none" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_50_67_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_50_67_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_50_67_Open_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_50_67_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_50_67_Open_Text"><span style="color: #000000">{&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;_user;&nbsp;}</span></span><span style="color: #000000"><br />
<img id="Codehighlighter1_76_94_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_76_94_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_76_94_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_76_94_Closed_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_76_94_Closed_Image" style="display: none" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_76_94_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_76_94_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_76_94_Open_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_76_94_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_76_94_Open_Text"><span style="color: #000000">{&nbsp;_user&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span></div>
<p style="text-align: left; tab-stops: list 36.0pt"></span><span style="font-size: 12pt; font-family: 宋体">不要使用Status做列名，它是NHibernate的保留字，否则ActiveRecord会抛异常：Ambiguous column name 'Status'<br />
</span><strong><span style="font-size: 12pt; font-family: 宋体">可以使用枚举作为列的类型</span></strong><span style="font-size: 12pt; font-family: 宋体">，在数据库中将创建整数类型的列</span> </p>
<h2>2 对象保存到数据库的时机</h2>
<p style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">只有在会话Flush()或事务Commit()的时候，对象才存入数据库</span> <br />
<span style="font-size: 12pt; font-family: 宋体">自动保存</span> <br />
<span style="font-size: 12pt; font-family: 宋体">&nbsp;* 当session.Find()被调用</span>&nbsp;<br />
<span style="font-size: 12pt; font-family: 宋体">&nbsp;* 当Filter()被调用</span>&nbsp;<br />
<span style="font-size: 12pt; font-family: 宋体">&nbsp;* 自动保存需要session.FlushMode为Auto（缺省值）</span> </p>
<h2>3 对象关系</h2>
<p style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">* 不支持在非主键上建立关系</span> <br />
<strong>3.1 BelongsTo<br />
</strong><span style="font-size: 12pt; font-family: 宋体">* 表现多对一的关系</span> <br />
<span style="font-size: 12pt; font-family: 宋体">* ActiveRecord</span><span style="font-size: 12pt; font-family: 宋体">将为该关系建立数据库表的外键</span> <br />
<span style="font-size: 12pt; font-family: 宋体">* 如&#8220;用户&#8221;相对于&#8220;部门", 在&#8220;用户&#8221;实体类上申明</span><span style="font-size: 12pt; font-family: 宋体">&nbsp;</span> <br />
<strong>3.2 HasMany<br />
</strong><span style="font-size: 12pt; font-family: 宋体">* 表现一对多的关系</span> <br />
<span style="font-size: 12pt; font-family: 宋体">* ActiveRecord</span><span style="font-size: 12pt; font-family: 宋体">将为该关系建立数据库表的外键</span> <br />
<span style="font-size: 12pt; font-family: 宋体">* 如&#8220;部门&#8221;相对于&#8220;用户", 在&#8220;部门&#8221;实体类上申明</span><span style="font-size: 12pt; font-family: 宋体"><span style="color: black"> </p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[HasMany(</span><span style="color: #0000ff">typeof</span><span style="color: #000000">(SystemUser))]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;IList</span><span style="color: #000000">&lt;</span><span style="color: #000000">SystemUser</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;Users<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000">&nbsp;{&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;_users;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000">&nbsp;{&nbsp;_users&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span></div>
<p style="text-align: left; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align="left"></span></span><strong>3.3 HasAndBelongsToMany<br />
</strong><span style="font-size: 12pt; font-family: 宋体">* 表现多对多的关系</span> <br />
<span style="font-size: 12pt; font-family: 宋体">* ActiveRecord</span><span style="font-size: 12pt; font-family: 宋体">将为创建一个关联表</span> <br />
<span style="font-size: 12pt; font-family: 宋体">* 如允许一个用户有多个角色的情况下的&#8220;用户&#8221;和&#8220;角色&#8221;</span> <br />
<strong>3.4 OneToOne<br />
</strong><span style="font-size: 12pt; font-family: 宋体">* 表现一对一的关系</span> <br />
<span style="font-size: 12pt; font-family: 宋体">* 两个实体(数据库表)拥有相同的数据库表主键，从表实体需将主键类型申明为PrimaryKeyType.Foreign</span> <br />
<span style="font-size: 12pt; font-family: 宋体">* 如&#8220;用户&#8221;和&#8220;用户地址&#8221;</span> <br />
<strong>3.5 Any 和 HasManyToAny<br />
</strong><span style="font-size: 12pt; font-family: 宋体">* 用于表示不确定一对多关系</span> <br />
<span style="font-size: 12pt; font-family: 宋体">* 如：&#8220;设备视频端口&#8221;可能保存多种设备(DVR/Matrix/DVS)的端口信息</span><span style="font-size: 12pt; color: black; font-family: 宋体"> </p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #000000">[ActiveRecord()]<br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;DeviceDvr&nbsp;:&nbsp;ActiveRecordBase,&nbsp;IVideoDeivce<br />
{&nbsp;<img alt="" src="http://www.cnblogs.com/Images/dot.gif" />&nbsp;}<br />
<br />
[ActiveRecord()]<br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;DeviceDvs&nbsp;:&nbsp;ActiveRecordBase,&nbsp;IVideoDeivce<br />
{&nbsp;<img alt="" src="http://www.cnblogs.com/Images/dot.gif" />&nbsp;}<br />
<br />
[Any(</span><span style="color: #0000ff">typeof</span><span style="color: #000000">(Guid),&nbsp;MetaType</span><span style="color: #000000">=</span><span style="color: #0000ff">typeof</span><span style="color: #000000">(</span><span style="color: #0000ff">string</span><span style="color: #000000">),TypeColumn</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">DeviceType</span><span style="color: #800000">"</span><span style="color: #000000">,IdColumn</span><span style="color: #000000">=</span><span style="color: #800000">"</span><span style="color: #800000">DeviceGuid</span><span style="color: #800000">"</span><span style="color: #000000">,Cascade</span><span style="color: #000000">=</span><span style="color: #000000">CascadeEnum.SaveUpdate)]<br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;IVideoDeivce&nbsp;VideoDeivce&nbsp;<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000">&nbsp;{&nbsp;<img alt="" src="http://www.cnblogs.com/Images/dot.gif" />&nbsp;}&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000">&nbsp;{&nbsp;<img alt="" src="http://www.cnblogs.com/Images/dot.gif" />&nbsp;}&nbsp;<br />
}<br />
</span></div>
<p style="text-align: left; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align="left"></span>&nbsp;</p>
<h2>4 实体类继承</h2>
<p><strong>4.1 单表继承</strong></p>
<p style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">&nbsp;* 所有父子实体类都保存在一个数据库表中</span> <br />
<span style="font-size: 12pt; font-family: 宋体">&nbsp;* &#8220;</span><span style="font-size: 12pt; font-family: 宋体">字典&#8221;、&#8220;设备类型字典&#8221;和&#8220;设备故障字典&#8221;</span><span style="font-size: 12pt; font-family: 宋体"> </p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;使用Type列来标示该行数据归属的字典类型&nbsp;</span><span style="color: #008000">*/</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;[ActiveRecord(DiscriminatorColumn&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">Type</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;DiscriminatorType&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">String</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;DiscriminatorValue&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">none</span><span style="color: #800000">"</span><span style="color: #000000">)]<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Dictionary&nbsp;:&nbsp;ActiveRecordBase</span><span style="color: #000000">&lt;</span><span style="color: #000000">Dictionary</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<img alt="" src="http://www.cnblogs.com/Images/dot.gif" />&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;[ActiveRecord(DiscriminatorValue&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">device_type</span><span style="color: #800000">"</span><span style="color: #000000">)]<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;DictionaryDeviceType&nbsp;:&nbsp;Dictionary<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;[ActiveRecord(DiscriminatorValue&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">device_failure</span><span style="color: #800000">"</span><span style="color: #000000">)]<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;DictionaryDeviceFailure&nbsp;:&nbsp;Dictionary<br />
</span></div>
<p style="text-align: left; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align="left"></span><strong>4.2 &nbsp;类表继承</strong></p>
<p style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">&nbsp;* 所有父子实体类各拥有一张数据库表，由基类生成主键</span> <br />
<span style="font-size: 12pt; font-family: 宋体">&nbsp;* 如： &#8220;汽车&#8221;、&#8220;跑车&#8221;和&#8220;房车&#8221;</span> </p>
<h3>5 嵌套的数据 Nested data</h3>
<p style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">&nbsp;* 支持用一个非数据库表的数据对象表现数据库表的一个或多个列的集合</span> <br />
<span style="font-size: 12pt; font-family: 宋体">&nbsp;* 如：&#8220;用户&#8221;、&#8220;单位&#8221;和&#8220;地址&#8221;，用户和单位表中都有地址信息，地址类只是多个列的集合</span> <br />
<span style="font-size: 12pt; font-family: 宋体">&nbsp;* 表现数据库中的一个列是，也可用于定义用户自定义数据，以实现数据库的用户定义数据类型</span>&nbsp;<br />
<span style="font-size: 12pt; font-family: 宋体">&nbsp;&nbsp; 。 如此可统一各个实体类中相同含义的列的格式定义（Sql数据类型、长度、格式验证等等）</span> <br />
<span style="font-size: 12pt; font-family: 宋体">&nbsp;&nbsp; 。 如：Emai地址、电话号码</span> </p>
<h3>6 延迟加载Lazy load</h3>
<p style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">&nbsp;* 延迟加载确保数据只在需要时才从数据库中加载，如&#8220;用户&#8221;对象中的&#8220;部门&#8221;在加载&#8220;用户&#8221;对象时不会被加载</span> <br />
<span style="font-size: 12pt; font-family: 宋体">&nbsp;* 如此启用实体的延迟加载： [ActiveRecord(Lazy=true)]</span> <br />
<span style="font-size: 12pt; font-family: 宋体">&nbsp;* 除了BelongTo，其他所有关系缺省的都未启用延迟加载</span> </p>
<h2>7 数据验证</h2>
<ul type="disc">
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">ActiveRecord</span><span style="font-size: 12pt; font-family: 宋体">提供数据验证器对列数据进行规则验证</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">验证器在数据库操作(insert,update)之前对数据格式进行验证</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">实体类需从ActiveRecordValidationBase继承</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">数据验证器包括：</span>
    <ul type="circle">
        <li style="text-align: left; tab-stops: list 72.0pt"><span style="font-size: 12pt; font-family: 宋体">ValidateIsUnique </span><span style="font-size: 12pt; font-family: 宋体">检查列值在表中唯一</span>
        <li style="text-align: left; tab-stops: list 72.0pt"><span style="font-size: 12pt; font-family: 宋体">ValidateRegExp </span><span style="font-size: 12pt; font-family: 宋体">使用正则表达式验证列数据格式</span>
        <li style="text-align: left; tab-stops: list 72.0pt"><span style="font-size: 12pt; font-family: 宋体">ValidateEmail </span><span style="font-size: 12pt; font-family: 宋体">验证列数据为EMail地址格式</span>
        <li style="text-align: left; tab-stops: list 72.0pt"><span style="font-size: 12pt; font-family: 宋体">ValidateNonEmpty </span><span style="font-size: 12pt; font-family: 宋体">验证列数据非空</span>
        <li style="text-align: left; tab-stops: list 72.0pt"><span style="font-size: 12pt; font-family: 宋体">ValidateConfirmation </span><span style="font-size: 12pt; font-family: 宋体">验证两个属性相同，如密码和密码确认</span> </li>
    </ul>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">可继承AbstractValidationAttribut来实现自定义验证器</span> </li>
</ul>
<h2>数据分页</h2>
<ul type="disc">
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">Query</span><span style="font-size: 12pt; font-family: 宋体"> </li>
</ul>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #000000">SimpleQuery</span><span style="color: #000000">&lt;</span><span style="color: #000000">SystemUser</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;userQuery&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;SimpleQuery</span><span style="color: #000000">&lt;</span><span style="color: #000000">SystemUser</span><span style="color: #000000">&gt;</span><span style="color: #000000">(</span><span style="color: #800000">"</span><span style="color: #800000">from&nbsp;SystemUser&nbsp;where&nbsp;State&nbsp;=&nbsp;:State&nbsp;Order&nbsp;By&nbsp;Name</span><span style="color: #800000">"</span><span style="color: #000000">);<br />
userQuery.SetParameter(</span><span style="color: #800000">"</span><span style="color: #800000">State</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;SystemUser.UserState.Valid);<br />
userQuery.SetQueryRange(pageIndex&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;pageSize,&nbsp;pageSize);<br />
SystemUser[]&nbsp;users&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;userQuery.Execute();<br />
</span></div>
<ul>
    <li>
    <div style="text-align: left; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align="left"></span><span style="font-size: 12pt; font-family: 宋体">SliceFindAll</span></div>
    </li>
</ul>
<p style="text-align: left; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align="left"><span style="font-size: 12pt; font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp; SystemUser<span style="color: black">[]</span> users = SystemUser.<span style="color: blue">SlicedFindAll</span><span style="color: black">(</span><span style="color: red">30</span>, <span style="color: red">10</span>, <span style="color: #0600ff">null</span>,</span><span style="font-size: 12pt; font-family: 宋体"><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: green">new</span></a> ICriterion<span style="color: black">[]</span> <span style="color: black">{</span> Expression.<span style="color: blue">Eq</span><span style="color: black">(</span><span style="color: gray">"State"</span>, SystemUser.<span style="color: blue">UserState</span>.<span style="color: blue">Valid</span><span style="color: black">)</span> <span style="color: black">})</span>;</span></p>
<h2>NHibernate用户自定义数据类型</h2>
<ul type="disc">
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">用于在单列中存储更复杂的数据信息（如列表），并以对象的形式来表现</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">应用场景：不想单独使用一个表来存储这些复杂的数据信息的时候</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">如：设备报警的端口列表可能为多个，可以将他们存在一个数据库列中,格式如"2,3,5"</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">表现该列的对象需实现NHibernate的IUserType接口，如</span><span style="font-size: 12pt; color: #0600ff; font-family: 宋体">public</span><span style="font-size: 12pt; font-family: 宋体"> <span style="color: red">class</span> DeiveAlarmPorts:List&lt;int&gt;,IUserType</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体">如此在DeviceAlarm类中声明属性</span> </li>
</ul>
<p style="text-align: left; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align="left"><span style="font-size: 12pt; font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: black">[</span>Property<span style="color: black">(</span><span style="color: gray">"AlarmPorts"</span>, <span style="color: gray">"ActiveRecordEntities.Alarm,ActiveRecordEntities"</span><span style="color: black">)]</span></span></p>
<p style="text-align: left; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align="left"><span style="font-size: 12pt; font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0600ff">public</span> DeiveAlarmPorts AlarmPorts <span style="color: black">{</span> get <span style="color: black">{</span>...<span style="color: black">}</span> set <span style="color: black">{</span>...<span style="color: black">}}</span></span></p>
<h2>引用和链接</h2>
<p style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 12pt; font-family: 宋体"><a title="ActiveRecord Official Document" href="http://www.castleproject.org/activerecord/documentation/trunk/index.html" target="_blank">ActiveRecord Official Document</a></span>&nbsp;&nbsp;&nbsp;&nbsp; <a title="自定义数据类型" href="http://www.cnblogs.com/renrenqq/archive/2006/08/02/458575.html">自定义数据类型</a></p>
<img src ="http://www.cnblogs.com/itrust/aggbug/1224190.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42097/" target="_blank">[新闻]微软CFO:仍对收购雅虎搜索业务感兴趣</a>]]></description></item><item><title>数据库开发的持续集成 - 方法和流程</title><link>http://www.cnblogs.com/itrust/archive/2008/06/17/1224141.html</link><dc:creator>251</dc:creator><author>251</author><pubDate>Tue, 17 Jun 2008 09:13:00 GMT</pubDate><guid>http://www.cnblogs.com/itrust/archive/2008/06/17/1224141.html</guid><wfw:comment>http://www.cnblogs.com/itrust/comments/1224141.html</wfw:comment><comments>http://www.cnblogs.com/itrust/archive/2008/06/17/1224141.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnblogs.com/itrust/comments/commentRss/1224141.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/itrust/services/trackbacks/1224141.html</trackback:ping><description><![CDATA[<p style="text-align: left" align="left"><span style="font-size: 9pt; font-family: 宋体"><strong>本系列文章目录<br />
</strong><span style="font-size: 10pt; font-family: 微软雅黑">&nbsp;&nbsp;&nbsp;&nbsp;<a title="数据库开发的持续集成 - Sql Server 部署升级工具" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html">数据库开发的持续集成 - Sql Server 部署升级工具</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;<a title="数据库开发的持续集成 - Sql Server数据库结构比较" href="http://www.cnblogs.com/itrust/archive/2008/06/05/1214156.html">数据库开发的持续集成 - Sql Server数据库结构比较</a><br />
&nbsp;&nbsp;&nbsp; <a class="entrylistItemTitle" id="CategoryEntryList1_EntryStoryList_Entries_ctl06_TitleUrl" href="http://www.cnblogs.com/itrust/archive/2008/06/17/1224141.html">数据库开发的持续集成 - 方法和流程</a><br />
&nbsp;&nbsp;&nbsp; <a class="entrylistItemTitle" id="CategoryEntryList1_EntryStoryList_Entries_ctl02_TitleUrl" href="http://www.cnblogs.com/itrust/archive/2008/06/20/1226374.html">数据库开发的持续集成 - Liquibase的简介和应用</a><br />
&nbsp;&nbsp;&nbsp; <a class="entrylistItemTitle" id="CategoryEntryList1_EntryStoryList_Entries_ctl00_TitleUrl" href="http://www.cnblogs.com/itrust/archive/2008/06/25/1229902.html">数据库的持续集成 - CruiseControl.Net的项目配置</a></span><br />
<br />
决定使用<a title="Castle ActiveRecord" href="http://www.cnblogs.com/itrust/archive/2008/06/17/1224190.html">Castle ActiveRecord</a>来开发新的系统，基于面向对象的思想将数据库设计转化为对象的代码设计，就可以将程序的持续集成开发自然引入数据库开发。再辅以liquibase，数据库的持续集成开发就可行了，也解决了数据库部署的问题。同时在引入liquibase后，数据库版本管理以及部署和升级也就简化了。<br />
<span style="color: #000080">当然，如果你不使用ActiveRecord开发数据库，也完全可以基于liquibase来实现自己的持续集成，只需稍作调整，将我流程中实体类的部分改换成数据库表的设计和测试即可。</span><br />
<br />
<strong>1 开发方法</strong></span></p>
<p style="text-align: left" align="left"><span style="font-size: 9pt; font-family: 宋体">使用领域驱动设计方法(Domain Driven Design)开发数据库,以面向对象的设计方法设计数据库表，具体方法包括：</span></p>
<ul style="margin-top: 0cm" type="disc">
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 9pt; font-family: 宋体">直接设计数据库实体类，然后使用ActiveRecord创建数据库表</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 9pt; font-family: 宋体">数据库表的一切属性（列类型、长度、约束、索引，表间关系等全部在实体类中设计）</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 9pt; font-family: 宋体">数据库访问层基于实体类实现，业务逻辑优先选择数据库访问层通过代码实现，除此之外的在存储过程中实现</span> </li>
</ul>
<p style="text-align: left" align="left"><strong><span style="font-size: 9pt; font-family: 宋体">2 数据库开发架构<br />
<img alt="" src="http://www.cnblogs.com/images/cnblogs_com/itrust/DatabaseDevelopArth.jpg" border="0" /><br />
</span></strong></p>
<ul style="margin-top: 0cm" type="disc">
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 9pt; font-family: 宋体">每个数据库开发人员必须在本地数据库实例上进行设计、编码和测试</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 9pt; font-family: 宋体">持续集成服务器通过监视SVN服务器上用户提交行为触发持续集成过程，在基线数据库上验证、部署新的数据库结构</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 9pt; font-family: 宋体">持续集成数据库上的基线数据库</span>
    <ul style="margin-top: 0cm" type="circle">
        <li style="text-align: left; tab-stops: list 72.0pt"><span style="font-size: 9pt; font-family: 宋体">其结构（包含数据库静态数据）为当前已发布系统的结构</span>
        <li style="text-align: left; tab-stops: list 72.0pt"><span style="font-size: 9pt; font-family: 宋体">只有持续集成过程能够修改基线数据库</span>
        <li style="text-align: left; tab-stops: list 72.0pt"><span style="font-size: 9pt; font-family: 宋体">开发人员只能通过持续集成过程来修改该数据库</span>
        <li style="text-align: left; tab-stops: list 72.0pt"><span style="font-size: 9pt; font-family: 宋体">开发人员可将基线数据库视为产品数据库，可通过将其与本地数据库进行比较得到数据库部署脚本</span> </li>
    </ul>
    </li>
</ul>
<p style="text-align: left" align="left"><strong><span style="font-size: 9pt; font-family: 宋体">3 数据库开发流程</span></strong></p>
<p style="text-align: left" align="left"><strong><span style="font-size: 9pt; font-family: 宋体">3.1 本地开发流程<br />
<img alt="" src="http://www.cnblogs.com/images/cnblogs_com/itrust/DatbaseDevProcedureLocal.jpg" border="0" /><br />
</span></strong></p>
<ul style="margin-top: 0cm" type="disc">
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 9pt; font-family: 宋体">所有设计和测试都在本地数据库上进行</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 9pt; font-family: 宋体">每一个访问层函数和较为复杂的实体类（如含外键关系）应有测试案例，必须通过测试</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 9pt; font-family: 宋体">数据库部署脚本的生成</span>
    <ul style="margin-top: 0cm" type="circle">
        <li style="text-align: left; tab-stops: list 72.0pt"><span style="font-size: 9pt; font-family: 宋体">在有多人设计数据库时需注意及时获取SVN上部署脚本在本地执行，与基线数据库保持一致</span>
        <li style="text-align: left; tab-stops: list 72.0pt"><span style="font-size: 9pt; font-family: 宋体">使用liquibase对比本地数据库和基线数据库，生成部署脚本</span>
        <li style="text-align: left; tab-stops: list 72.0pt"><strong><span style="font-size: 9pt; font-family: 宋体">注意：已发布的数据库部署脚本不可更改</span></strong> </li>
    </ul>
    </li>
</ul>
<p style="text-align: left" align="left"><strong><span style="font-size: 9pt; font-family: 宋体">3.2 持续集成流程<br />
3.2.1 Trunk流程<br />
<img alt="" src="http://www.cnblogs.com/images/cnblogs_com/itrust/DatabaseCIProcedureTrunk.jpg" border="0" /><br />
</span></strong></p>
<ul style="margin-top: 0cm" type="disc"><span style="font-size: 9pt; font-family: 宋体">
    <li>此流程先升级基线数据库GTCA，然后在基线数据库上做持续集成（以保证新的程序集和升级脚本兼容以发布的产品系统）
    <li>上图中任一流程发生错误都导致持续集成失败，数据库回滚到集成前的状态
    <li>通过数据库文档可查看所有数据库结构修改日志 </li>
</ul>
<p><strong>3.2.2 Studio流程</strong></p>
<p></span><img alt="" src="http://www.cnblogs.com/images/cnblogs_com/itrust/DatabaseCIProcedureStudio.jpg" border="0" /></p>
<ul>
    <li style="font-size: 8pt"><span style="font-size: 10pt; font-family: 宋体">此流程通过创建临时数据库GTCATest，开展测试工作</span> </li>
</ul>
<p style="text-align: left" align="left"><strong><span style="font-size: 9pt; font-family: 宋体">4 编码原则</span></strong></p>
<ul style="margin-top: 0cm" type="disc">
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 9pt; font-family: 宋体">放弃使用Sql Server的domain,rule,default等（rule和default在2005中不被支持）</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 9pt; font-family: 宋体">使用ActiveRecord的Nested Data替代domain</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 9pt; font-family: 宋体">通过对Nested Data所进行ActiveRecord定义实现rule和default</span>
    <li style="text-align: left; tab-stops: list 36.0pt"><span style="font-size: 9pt; font-family: 宋体">谨慎使用视图和存储过程</span> </li>
</ul>
<p style="text-align: left" align="left">考量我目前的新系统开发，这个方法和流程还是可行的，估计在实践中还会有很多问题出现，希望发现问题的园友不吝赐教。<br />
<br />
<span style="color: red">Update 20080620</span> 关于liquibase,请参见<a title="数据库开发的持续集成 - Liquibase的简介和应用" href="http://www.cnblogs.com/itrust/archive/2008/06/20/1226374.html">数据库开发的持续集成 - Liquibase的简介和应用</a><br />
<span style="color: red">Update 20080625</span> 根据实际应用的情况，修正了一下流程, 并发布<a title="数据库的持续集成-CruiseControl.Net的配置" href="http://www.cnblogs.com/itrust/archive/2008/06/25/1229902.html">数据库的持续集成-CruiseControl.Net的配置</a><br />
&nbsp;&nbsp;&nbsp;&nbsp; 主要的修正在于考虑测试代码在本地，持续集成服务器上的Studio项目和Trunk项目中都能够使用，且满足下列要求<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Trunk项目中测试代码直接在升级后的基线数据库上测试（以保证新发布的代码和脚本在兼容已发布的产品数据库），因此不允许修改数据库结构<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Studio项目在测试数据库上测试</p>
 <img src ="http://www.cnblogs.com/itrust/aggbug/1224141.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42097/" target="_blank">[新闻]微软CFO:仍对收购雅虎搜索业务感兴趣</a>]]></description></item><item><title>数据库开发的持续集成 - Sql Server数据库结构比较</title><link>http://www.cnblogs.com/itrust/archive/2008/06/05/1214156.html</link><dc:creator>251</dc:creator><author>251</author><pubDate>Thu, 05 Jun 2008 02:37:00 GMT</pubDate><guid>http://www.cnblogs.com/itrust/archive/2008/06/05/1214156.html</guid><wfw:comment>http://www.cnblogs.com/itrust/comments/1214156.html</wfw:comment><comments>http://www.cnblogs.com/itrust/archive/2008/06/05/1214156.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cnblogs.com/itrust/comments/commentRss/1214156.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/itrust/services/trackbacks/1214156.html</trackback:ping><description><![CDATA[<p><span style="font-size: 10pt; font-family: 微软雅黑"><a title="数据库开发的持续集成 - Sql Server 部署升级工具" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html"><strong>本系列文章目录<br />
</strong><span style="font-size: 10pt; font-family: 微软雅黑">&nbsp;&nbsp;&nbsp;&nbsp;</a><a title="数据库开发的持续集成 - Sql Server 部署升级工具" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html">数据库开发的持续集成 - Sql Server 部署升级工具</a><a title="数据库开发的持续集成 - Sql Server 部署升级工具" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</a><a title="数据库开发的持续集成 - Sql Server数据库结构比较" href="http://www.cnblogs.com/itrust/archive/2008/06/05/1214156.html">数据库开发的持续集成 - Sql Server数据库结构比较</a><a title="数据库开发的持续集成 - Sql Server 部署升级工具" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html"><br />
&nbsp;&nbsp;&nbsp; </a><a class="entrylistItemTitle" id="CategoryEntryList1_EntryStoryList_Entries_ctl06_TitleUrl" href="http://www.cnblogs.com/itrust/archive/2008/06/17/1224141.html">数据库开发的持续集成 - 方法和流程</a><a title="数据库开发的持续集成 - Sql Server 部署升级工具" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html"><br />
&nbsp;&nbsp;&nbsp; </a><a class="entrylistItemTitle" id="CategoryEntryList1_EntryStoryList_Entries_ctl02_TitleUrl" href="http://www.cnblogs.com/itrust/archive/2008/06/20/1226374.html">数据库开发的持续集成 - Liquibase的简介和应用</a><a title="数据库开发的持续集成 - Sql Server 部署升级工具" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html"><br />
&nbsp;&nbsp;&nbsp; </a><a class="entrylistItemTitle" id="CategoryEntryList1_EntryStoryList_Entries_ctl00_TitleUrl" href="http://www.cnblogs.com/itrust/archive/2008/06/25/1229902.html">数据库的持续集成 - CruiseControl.Net的项目配置</a></span></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<a title="上回" href="http://www.cnblogs.com/itrust/archive/2008/05/30/1210733.html">上回</a>说到了<font face="Verdana">数据库开发的持续集成</font>的总的意图，提供一个数据库部署和升级的工具，接下来说说如何进行数据库比较。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;在我的开发中数据库比较工具主要需要两种形式： 桌面工具和MsBuid任务。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;桌面工具推荐开源的<a title="DaBCoS3" href="http://sourceforge.net/projects/dabcos/">DaBCoS3</a>，基本够用,有朋友推荐直接用VS2005，但我比较喜欢小巧一点的东东，因为不仅仅在数据库开发的时候用。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;MsBuild任务很重要，在持续集成的时候可用来验证升级脚本是否正常工作。在CC.Net中加入SqlDeply任务（MsBuild），对产品系统数据库的副本进行升级，然后使用MsBuild数据库比较任务比较升级后的结构与开发数据库是否相同。以此来验证升级脚本，相当于对升级脚本做自动测试（当然还有回归测试），可大大节约人力。<br />
&nbsp;&nbsp;&nbsp;&nbsp;在网上搜寻一大圈，发现Red Gate提供的程序集不错，但要$，放弃。绕了一大圈，回到M$，<a title="PowerTools" href="http://www.cnblogs.com/Files/itrust/VSDBProPT.7z">PowerTools</a>被选中。要先装Team Edition for Database。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;数据结构比较的MsBuild任务如此例：<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">Project&nbsp;</span><span style="color: #ff0000">DefaultTargets</span><span style="color: #0000ff">="SchemaCompare"</span><span style="color: #ff0000">&nbsp;xmlns</span><span style="color: #0000ff">="http://schemas.microsoft.com/developer/msbuild/2003"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">UsingTask&nbsp;</span><span style="color: #ff0000">TaskName</span><span style="color: #0000ff">="SqlSchemaCompareTask"</span><span style="color: #ff0000">&nbsp;AssemblyName</span><span style="color: #0000ff">="Microsoft.VisualStudio.TeamSystem.Data.PowerTools.Tasks,&nbsp;Version=2.0.0.0,&nbsp;Culture=neutral,&nbsp;PublicKeyToken=b03f5f7f11d50a3a"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">PropertyGroup</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">UpdateSql</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">PropertyGroup</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Target&nbsp;</span><span style="color: #ff0000">Name&nbsp;</span><span style="color: #0000ff">="SchemaCompare"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">SqlSchemaCompareTask<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000">SourceConnectionString</span><span style="color: #0000ff">="server=product;user&nbsp;id=sa;password=mypass"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SourceDatabaseName</span><span style="color: #0000ff">="Northwind"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TargetConnectionString</span><span style="color: #0000ff">="Data&nbsp;Source=.;Integrated&nbsp;Security=True;Pooling=False"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TargetDatabaseName</span><span style="color: #0000ff">="Northwind"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutputPath</span><span style="color: #0000ff">=&nbsp;"."</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutputFileName&nbsp;</span><span style="color: #0000ff">=&nbsp;"update.sql"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ForceColumnOrder</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IgnoreExtendedProperties</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IgnoreStatistics</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000">&nbsp;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IgnoreConstraintNames</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IgnoreQuotedIdentifiersAndAnsiNullSettings</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IgnoreTriggerOrder</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IgnoreUsers</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IgnoreWhiteSpace</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DoNotOutputCommentHeader</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NoTransactionalChangeScript</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SkipSETStatements</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ScriptCollationWhenDifferentFromDefault</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ReadLinesFromFile&nbsp;</span><span style="color: #ff0000">File</span><span style="color: #0000ff">="update.sql"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Output&nbsp;</span><span style="color: #ff0000">TaskParameter</span><span style="color: #0000ff">="Lines"</span><span style="color: #ff0000">&nbsp;PropertyName</span><span style="color: #0000ff">="UpdateSql"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ReadLinesFromFile</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;NOTE:&nbsp;If&nbsp;update.sql&nbsp;is&nbsp;emtpy,&nbsp;the&nbsp;two&nbsp;databases&nbsp;are&nbsp;same&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Message&nbsp;</span><span style="color: #ff0000">Text</span><span style="color: #0000ff">="$(UpdateSql)"</span><span style="color: #ff0000">&nbsp;Condition</span><span style="color: #0000ff">="'$(UpdateSql)'&nbsp;!=&nbsp;''"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Error&nbsp;</span><span style="color: #ff0000">Text</span><span style="color: #0000ff">="Soure&nbsp;database&nbsp;is&nbsp;different&nbsp;from&nbsp;the&nbsp;target"</span><span style="color: #ff0000">&nbsp;Condition</span><span style="color: #0000ff">="'$(UpdateSql)'&nbsp;!=&nbsp;''"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Target</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Project</span><span style="color: #0000ff">&gt;</span></div>
&nbsp;&nbsp;&nbsp;&nbsp;注意：此例中SqlSchemaComapreTask的属性目前已优化，用以确保在数据库相同时产生的update.sql是空的，并以此来判断两个数据库是否相等。这个任务用来产生升级脚本的，这里只用于比较两个数据库是否结构相同。<br />
<br />
&nbsp;&nbsp;&nbsp; 数据库数据比较的MsBuild任务如此例：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">Project&nbsp;</span><span style="color: #ff0000">DefaultTargets</span><span style="color: #0000ff">="DataCompare"</span><span style="color: #ff0000">&nbsp;xmlns</span><span style="color: #0000ff">="http://schemas.microsoft.com/developer/msbuild/2003"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">UsingTask&nbsp;</span><span style="color: #ff0000">TaskName</span><span style="color: #0000ff">="SqlDataCompareTask"</span><span style="color: #ff0000">&nbsp;AssemblyName</span><span style="color: #0000ff">="Microsoft.VisualStudio.TeamSystem.Data.PowerTools.Tasks,&nbsp;Version=2.0.0.0,&nbsp;Culture=neutral,&nbsp;PublicKeyToken=b03f5f7f11d50a3a"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Target&nbsp;</span><span style="color: #ff0000">Name&nbsp;</span><span style="color: #0000ff">="DataCompare"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">SqlDataCompareTask<br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000">SourceConnectionString</span><span style="color: #0000ff">="server=product;user&nbsp;id=sa;password=mypass"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SourceDatabaseName</span><span style="color: #0000ff">="Northwind"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TargetConnectionString</span><span style="color: #0000ff">="Data&nbsp;Source=.;Integrated&nbsp;Security=True;Pooling=False"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TargetDatabaseName</span><span style="color: #0000ff">="Northwind"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutputPath&nbsp;</span><span style="color: #0000ff">=&nbsp;"."</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutputFileName&nbsp;</span><span style="color: #0000ff">=&nbsp;"TestDataCompare.sql"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TrimTrailingSpaces</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DisableTriggers</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DisableKeys</span><span style="color: #0000ff">="false"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DoNotOutputCommentHeader</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DoNotUseTransactions</span><span style="color: #0000ff">="true"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Target</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Project</span><span style="color: #0000ff">&gt;</span></div>
<br />
&nbsp;<span style="color: red">Update 20060617<br />
</span><font color="#ff0000">&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000"><font color="#ff0000">最终我选定了Java下的liquibase作为数据库比较、升级、部署的工具，已应用在数据库持续集成开发项目中（参见<a title="方法和流程" href="http://www.cnblogs.com/itrust/archive/2008/06/17/1224141.html">方法和流程</a>），感觉不错，唯一缺憾就是暂时还不支持.Net</font> </span></font>
<img src ="http://www.cnblogs.com/itrust/aggbug/1214156.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42095/" target="_blank">[新闻]SQL Server2008十月亮相 标榜智能数据平台</a>]]></description></item></channel></rss>