<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="css/rss.xslt"?>
<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>MacGoo</title><link>http://www.macgoo.com/myblog/</link><description>梦想开始的地方</description><generator>RainbowSoft Studio Z-Blog 1.8 Arwen Build 90619</generator><language>zh-CN</language><copyright>Powered By Z-Blog Copyright 2006-2009 Macgoo.com Some Rights Reserved.Theme Design By Design Disease | Transplant by Nobird湘ICP备07001810号var gaJsHost = ((&amp;quot;https:&amp;quot; == document.location.protocol) ? &amp;quot;https://ssl.&amp;quot; : &amp;quot;http://www.&amp;quot;);document.write(unescape(&amp;quot;%3Cscript src='&amp;quot; + gaJsHost + &amp;quot;google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E&amp;quot;));try {var pageTracker = _gat._getTracker(&amp;quot;UA-5293693-2&amp;quot;);pageTracker._trackPageview();} catch(err) {}</copyright><pubDate>Tue, 31 Aug 2010 16:24:12 +0800</pubDate><item><title>EducationSupport项目总结</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/157/</link><pubDate>Tue, 31 Aug 2010 14:12:09 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/157/</guid><description><![CDATA[<p>&nbsp;&nbsp; &nbsp; 如果说前面的<a target="_blank" href="http://www.macgoo.com/myblog/archives/153/">eWindow</a>是个铺垫的话,这个EducationSupport教学支持项目(下简称ES)则是个尽善尽美不错的作品.</p>
<p>&nbsp;&nbsp; &nbsp; 系统是根据某个比赛的需求,确实,如您所见,这又是个一个参加比赛的项目.在放假的前几天,主办方发给我们一个pdf,上面写着一些模糊的需求,开始我们对其中的很多需求不确定性征求了主办方的意见,就像我们学生组织一样,他们也是再三推脱,然后又回话&quot;自己想&quot;.可想而知比赛是个什么样的形式,所以我都不敢把那比赛说出来.</p>
<p>&nbsp;&nbsp; &nbsp; 由于需求模糊,所以只能自行推敲,结果还好有老师们多年从教经验,而不至于为某个功能的定义大伤脑经.这就是需求.<br />
&nbsp;&nbsp; &nbsp; 在设计里,原来安排的是:<a target="_blank" href="http://dbentry.codeplex.com/">DbEntry.net</a> + ES.Framework + <a target="_blank" href="http://www.asp.net/mvc">ASP.net MVC</a> + <a target="_blank" href="http://www.sencha.com/">Ext</a> ,之类已经上手很多次了,中间除了ES.Framework需要自行实现,ASP.net MVC需要学习,其他的部分都很熟悉了(Ext是上一个项目里实践过了的),不过老师又说这是&quot;微软的比赛&quot;,不得不考虑微软的封闭?(这句话值得商榷),所以尽量用微软的自家产品.于是就有了下面的架构图.</p>
<p>&nbsp;</p>
<p style="text-align: center; "><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008311617303313.jpg" alt="" title="" /></p>
<p style="text-align: left; ">&nbsp;&nbsp; &nbsp;数据层换成了EntityFramework,虽然demo看上去很好用,但为了减少依赖,所以自己在上面封装了一层DataService,它负责EF的调用,以及数据库的开关.业务逻辑做药是权限以及复杂逻辑的实现.表现层则主要是WEB上面的,放弃了原来的Ext,改用jQuery,虽然二者谈不上一个量级,为什么不用ASP.net AJAX ? 学习成本,代码风格,以及jQuery实在是太普及了,微软都首推他.所以我们就用他加上Asp.netMVC带给我们的职责分离,为开发分清思路.</p>
<p style="text-align: left; ">&nbsp;&nbsp; &nbsp;//待续.下图为讲解用的幻灯</p>
<p style="text-align: center; "><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008311623535323.jpg" alt="" title="" /></p>]]></description><category>Programer</category><comments>http://www.macgoo.com/myblog/archives/157/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=157</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=157&amp;key=9f8ceeaf</trackback:ping></item><item><title>两个按钮,提高您的阅读效率</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/156/</link><pubDate>Sun, 29 Aug 2010 02:39:22 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/156/</guid><description><![CDATA[<p>&nbsp;翻译自:http://www.hanselman.com/blog/TwoMustHaveToolsForAMoreReadableWeb.aspx</p>
<p>&nbsp;&nbsp; &nbsp;大多数人都是如何使用网络?您在邮件,QQ,Twitter,Facebook等等程序里在新的标签里打开他们带来的连接.</p>
<p><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008290251407320.png" alt="" title="" /></p>
<p>&nbsp;&nbsp; &nbsp;然后,等到某个闲暇的时间,阅读这些打开的标签,对不对?更甚,某些文章有8页长,让您不得不提前打开几个页面来加载他.然后也许在您的浏览器崩溃或者系统重启的时候才想起来,你为什么要打开他.</p>
<p>&nbsp;&nbsp; &nbsp;这是不理智的,我拒绝使用这种方式浏览网站,下面是我的做法.</p>
<p>&nbsp;&nbsp; &nbsp;考虑下面的新的流程,看过之后,您将会决定是现在阅读他,还是以后再阅读.</p>
<p><strong>首先,决定阅读先后</strong></p>
<p>&nbsp;</p>
<p><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008290253464681.png" alt="" title="" /></p>
<p>&nbsp;&nbsp; &nbsp;当您发现您要阅读的东西很长时,即便您确定您需要阅读他,但您就是没有时间了,不要打开一个标签.将他保存到<strong><a target="_blank" href="http://www.instapaper.com/">Instapaper</a></strong>中去,在我所有的电脑上的所有浏览器里都有一个<strong><a target="_blank" href="http://www.instapaper.com/">Instapaper</a></strong>书签,这很重要.</p>
<p>&nbsp;</p>
<p><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008290258204603.png" alt="" title="" /></p>
<p>&nbsp;&nbsp; &nbsp;如果没有他,您将会退回到原始的使用浏览器标签保存将要阅读的文章连接的不好习惯.用10分钟去适应它.即使在GoogleReader中,您也可以使用它.此后的任何时间里,只要您需要,您就可以从<strong><a target="_blank" href="http://www.instapaper.com/">Instapaper</a></strong>阅读列表里找到他,即刻打开开始阅读.</p>
<p>例子:</p>
<p>&nbsp;&nbsp; &nbsp;比如,我看到<span class="Apple-style-span" style="font-family: arial; line-height: normal; font-size: 13px; ">Phil Haack的某条消息,他能说会道,消息很有趣,我决定阅读他,但是我现在很忙.</span></p>
<p>&nbsp;</p>
<p><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008290305236071.png" alt="" title="" /></p>
<p>&nbsp;&nbsp; &nbsp;我在书签栏里单击&quot;Read Later&quot;,接下来会出现提示.</p>
<p>&nbsp;</p>
<p><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008290307115333.png" alt="" title="" /></p>
<p>&nbsp;&nbsp; &nbsp;此后的几个小时里,我忙完了,有空闲时间了,并且我已经收集了一些有趣的阅读连接,我很期待阅读这些有意思的东东,于是我打开Instapaper,看看这个:</p>
<p>&nbsp;</p>
<p><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008290309342138.png" alt="" title="" /></p>
<p>&nbsp;&nbsp; &nbsp;这里就是我保存的阅读连接,第一次的时候都还是新的,它知道我阅读了些什么,以及什么时候保存的,什么时候阅读的.</p>
<p>&nbsp;&nbsp; &nbsp;这里有一个值得注意的地方,当我打开其中的连接时,Instapapers为我设置了一个可读性过滤器,他删除了页面的一些不必要的部分,还在顶部增加了一个小工具栏,可以设置字体,大小,宽度和行距等等.这里的一切都是为了我的阅读,这使得我阅读更加舒适了.</p>
<p>&nbsp;</p>
<p><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008290310096630.png" alt="" title="" /></p>
<p>&nbsp;&nbsp; &nbsp;当然,我也可以从Iphone中阅读,当然,其他设备也行,都是同样的一个阅读列表.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008290316151123.png" alt="" title="" />&nbsp;<img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008290316254588.png" alt="" title="" /></p>
<p><strong>然后,开始阅读 - 可读性</strong></p>
<p>&nbsp;&nbsp; &nbsp;有时候我会有想阅读某个页面的想法,但是页面复杂得就像迷宫一样,让我无法流畅阅读.</p>
<p>&nbsp;&nbsp; &nbsp;好在,我的工具栏里还有一个叫做&quot;<span class="Apple-style-span" style="font-family: 'segoe ui', tahoma, verdana, 'lucida grande', 'lucida sans unicode', sans-serif; line-height: 18px; font-size: 13px; "><a href="http://lab.arc90.com/experiments/readability/" style="font-weight: bold; text-decoration: none; color: rgb(51, 51, 51); ">Readability</a></span>&quot;的书签.</p>
<p>&nbsp;</p>
<p><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008290320485863.png" alt="" title="" /></p>
<p>&nbsp;&nbsp; &nbsp;就在这里</p>
<p>&nbsp;</p>
<p><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008290321140411.png" alt="" title="" /></p>
<p>&nbsp;&nbsp; &nbsp;就像<font class="Apple-style-span" face="Arial" size="4"><span class="Apple-style-span" style="font-size: 14px; line-height: 22px; white-space: pre-wrap;">顾城</span></font><span class="Apple-style-span" style="font-family: Arial; line-height: 22px; font-size: 14px; white-space: pre-wrap; "><span class="Apple-style-span" style="font-family: Arial, Verdana, sans-serif; line-height: 19px; white-space: normal; font-size: 12px; ">所说&quot;黑夜给了我黑色的眼睛,我却用它来寻找光明&quot;.</span></span></p>
<p>&nbsp;</p>
<p><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/8/201008290322153757.png" alt="" title="" /></p>
<p>&nbsp;&nbsp; &nbsp;我这里有一些关于这两个标签的介绍,<span class="Apple-style-span" style="font-family: 'segoe ui', tahoma, verdana, 'lucida grande', 'lucida sans unicode', sans-serif; line-height: 18px; font-size: 13px; ">&nbsp;<a href="http://www.instapaper.com/" style="font-weight: bold; text-decoration: none; color: rgb(51, 51, 51); ">Instapaper for Reading Later</a>&nbsp;和&nbsp;<a href="http://lab.arc90.com/experiments/readability/" style="font-weight: bold; text-decoration: none; color: rgb(51, 51, 51); ">Readability for Reading Now</a>&nbsp;,不仅仅使得我花更少的时间获取更多信息,而且也是我远离了那可怕的43个标签.</span></p>
<p>&nbsp;</p>]]></description><category>Booooer.</category><comments>http://www.macgoo.com/myblog/archives/156/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=156</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=156&amp;key=c0085640</trackback:ping></item><item><title>[UML和OOAD快速入门]读后感</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/155/</link><pubDate>Tue, 17 Aug 2010 22:58:41 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/155/</guid><description><![CDATA[<p>&nbsp;&nbsp; &nbsp; 邱郁惠老师的&lt;<a target="_blank" href="http://www.china-pub.com/196750">UML和OOAD快速入门</a>&gt;<br />
&nbsp;&nbsp; &nbsp; 我出于瞧瞧架构师,设计师们的门道的目的买了此书.当然这批书单不仅仅只有这本,还有许多其他方面的.</p>
<p><br />
&nbsp;&nbsp; &nbsp; 在平时的项目中,我很难抉择到底该如何下手,虽然数据库建了,但是感觉无根无据,后面肯定要乱七八糟的改,而用例图和流程图很大程度上都没能束缚编码,因为流程图和用例图实在是太大了,而数据库设计只能作为实体类的一个依据,根本无法提供编码依据,所以很多时候都是依靠程序员自己的修为,来决定代码的质量.只有一个人还好,但是超过三个人我就感觉这不像商品而像是艺术品了,多种不同的风格夹杂在项目里,不易维护不说,这样的代码能够正常维护下去都难.所以需要一些东西来帮助我们开发,于是我想到了UML.<br />
&nbsp;&nbsp; &nbsp; 知道了用例图,类图和序列图搭配在一起,就能够很好的指挥代码.用例图给与了响应的场景与不同的参与者,序列图则更一步细化了流程图,详细了代码框架,指出实现的类该是接受哪些参数取得那些结果,包括命名也都一并给出来了.只差一些私有帮助函数没有明确指出.<br />
&nbsp;&nbsp; &nbsp; 这样就有一个好处,给与了基本的大体框架,而且在这三图中,能够想到业务的很细部分,从而三图一并修改,就像三个齿轮,缺一不可.他们是联动的.<br />
&nbsp;&nbsp; &nbsp; 以前拿捏不准到底是该从界面做起,还是从底层数据做起,虽然各有各的道理,但是很容易出现短截的现象,界面做到下面会发现很多重复的东西,从底层做到上面会突然发现忘记了当时约定好的界面需要的某些要素.但是有了这些图的帮助,基本上都能并行开发,因为有了图约束,项目能够很流畅的进行,出现问题的时候也有了查找是哪个环节出错的依据.可以说是设计到编码的沟通桥梁.</p>
<p>&nbsp;&nbsp; &nbsp; 但是缺点是显而易见的,整书只有一个案例,几个场景,我几个钟头的功夫就看完了,大呼不过瘾.不过书名就叫&quot;快速入门&quot;,我这确实&quot;快速&quot;了,可感觉UML的门道应该远不止如此,所以这&quot;入门&quot;还是有待商榷.总之不失为一本拓展视野的好书.</p>]]></description><category>Booooer.</category><comments>http://www.macgoo.com/myblog/archives/155/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=155</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=155&amp;key=45be72cb</trackback:ping></item><item><title>找准自己的位置[转载]</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/154/</link><pubDate>Tue, 10 Aug 2010 23:36:03 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/154/</guid><description><![CDATA[<p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="Apple-style-span" style="font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; line-height: 21px; font-size: 14px; color: rgb(57, 57, 57); "><span class="Apple-style-span" style="font-family: 宋体; ">同样的一瓶饮料，便利店里2块钱，五星饭店里60块。很多时候，一个人的价值取决于所在的位置。<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: 宋体; "><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
</span></span>
<p style="margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 0px; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-family: 宋体; ">&nbsp;&nbsp; &nbsp;求索是一门艺术，放弃更是一种艺术，在这中间，唯一的目标是找到自己的位置。&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
&nbsp;&nbsp;&nbsp;&nbsp;朋友跟我抱怨，说他不知道现在该怎么办才好，是该坚持下去呢，还是就此放弃，寻一条新路。我知道他在说什么。他放弃了自己以前的工作，费了好多力气进了一家报社，可是每个月他的发稿量少得惊人，奖金很低，现在生活都成了问题，这就是他这段时间以来的处境。&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
&nbsp;&nbsp;&nbsp;&nbsp;我没有跟他绕圈子，我说，你还是放弃吧，有些事情是靠天赋的，不是说光凭后天的汗水就能达到的，我们承认它，不是意味着我们的怯弱，而是说我们比较理智地对待我们自身的局限。&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
&nbsp;&nbsp;&nbsp;&nbsp;我们受到太多的教育和劝导&mdash;&mdash;只要努力就一定会成功，也似乎有许多事例向我们证明，要取得成功，要让自己的人生变得更有价值更值得尊重，就需要更多的汗水。看起来，这真的像是一条颠扑不破的真理，因为没有人能够随便就成功的，要达到目标当然就要作一番努力。可是残酷的现实又告诉我们，取得了成功的人是何其少啊，很多人甚至付出了多倍的努力却依然没有达到自己的目标。当然我们还可以坚持下去，也有好多的理由来催眠，比如说&ldquo;胜利就在前方了，再坚持一点点，事就成了&rdquo;。我们总会说自己的努力不够，而从不愿意想想自己合适不合适我们所选择的方向。&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
&nbsp;&nbsp;&nbsp;&nbsp;求索是一门艺术，放弃更是一种艺术，在这中间，唯一的目标是找到自己的位置。 &ldquo;一个人应该知道自己希望做什么，应该做什么，必须做什么&rdquo;，要知道自己的界限，知道什么该坚持，知道什么该放弃，知道怎么样更合适自己的特点。于是，我们就不需要做一个成功的人，只需要做一个找准了自己位置的人，成功就成了附属品了。&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
&nbsp;&nbsp;&nbsp;&nbsp;还记得赖斯吗，一个完全的草根，凭借自己的努力成了华盛顿&ldquo;最有权力的女人&rdquo;。从一个在种族歧视下长大的黑人到美国现国务卿，没有人否认她的努力，可是我们是否更应该看到她在16岁那年所作的决定呢？她小时候想成为钢琴家，她钢琴的确也弹得不错。16岁那年她进入丹佛大学音乐学院学习钢琴，梦想成为职业钢琴家。但是，在著名的阿斯本音乐节上，她受了打击。&ldquo;我碰到了一些11岁的孩子们，他们只看一眼就能演奏那些我要练一年才能弹好的曲子，&rdquo;她说，&ldquo;我想我不可能有在卡内基大厅演奏的那一天了。&rdquo;于是她重新设计自己的未来，所幸她找到了自己的新目标，她投身于国际政治中，经过一番努力取得了今天的成就。&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
&nbsp;&nbsp;&nbsp;&nbsp;美国国务卿与钢琴家相比，哪个更有价值些，似乎没有绝对的可比性，可是对赖斯来说，成为美国国务卿与成为钢琴家，哪个更有可能性些，这个就很容易判断了。哪个更适合她成功的道路，哪个就是她赖斯的位置。&nbsp;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />
&nbsp;&nbsp;&nbsp;&nbsp;找准自己的位置，不要以为这很容易。现在的好位置不代表正确的位置，&ldquo;认识你自己&rdquo;从来都是难的。只有坚持认清自己，找到一个最适合自己发展的位置，像螺丝钉一样深入下去，才能取得最后成功。</span></p>
</span></p>]]></description><category>Booooer.</category><comments>http://www.macgoo.com/myblog/archives/154/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=154</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=154&amp;key=64d25011</trackback:ping></item><item><title>eWindow项目总结</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/153/</link><pubDate>Tue, 10 Aug 2010 21:58:15 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/153/</guid><description><![CDATA[<p>&nbsp;&nbsp; &nbsp; 这本该是半年以前该做的事了.</p>
<p>&nbsp;&nbsp; &nbsp; 这个项目前前后后折腾了近半年.在项目开始的时候,我在弄一个比赛,在那比赛的时候挺2的,没能夺魁.回来后项目也进行了近一个月.可丝毫没有进展的样子.还只是模模糊糊的画出了数据库设计.<br />
&nbsp;&nbsp; &nbsp; 项目分为三组,开始定好每组五人,结果因为童鞋们兴趣挺浓,就每组多了一人.<span style="background-color: rgb(255, 204, 153); ">整整十八个人,花了半年时间</span>,就折腾出这么个东西,也只想到欲哭无泪这个词儿来形容了.<br />
&nbsp;&nbsp; &nbsp; 项目一开始我也是满心欢喜的参加,由于参加比赛的原因,不能一开始带领大家,于是组长的位置放给了另外一名童鞋.比赛结束之后,因为我个人的一些主张,以及从事风格和他大相径庭,最后是不欢而散,他退出了.他也是一个学习成绩不错的孩子,只可惜还停留在填鸭式的教学上去学习编程.每天完成老师布置的任务,几道哄小孩的题上面,然后看电影,玩游戏荒废光阴.这是题外话了.总之各组之内也出现了人员的调整,这一个小调整就为后面项目的进行造成了不小的阻力.</p>
<p>&nbsp;&nbsp; &nbsp; 项目的进度,十月份开始项目,我十一月过半比完赛参加,中间断断续续的,因为都是鼓捣.Net的,而需求方要求使用J2EE,然后是一些框架的堆砌,Struts2+Hibernate3,这里没有用到Spring,需求方也没提,可能是出于降低项目难度的原因吧,因为依赖倒置之类的抽象理念对于<span style="background-color: rgb(255, 204, 153); ">为什么还要使用类都没琢磨透</span>的童鞋们老说是有那么一点儿不可及.十一月十二月做需求,放寒假的时候还额外留了童鞋们半个多月,半个月前项目都没出来,半个月后都已经定型了,可以说主要的进度都是在这半个月里面出来的.之后来年三月四月修补BUG,最后交稿.</p>
<p>&nbsp;&nbsp; &nbsp; 项目中的问题:<br />
&nbsp;&nbsp; &nbsp; 1.环境问题,说实话,我现在在Eclipse(MyEclipse)下写代码还是有那么些力不从心,各式各样的插件,遍布到处的报错,让人纠结的代码提示(是的,我是被VS惯坏了的孩子),奇怪的调试方式.种种种种的不适.首先是要去找各式各样的插件,而且这些插件由于是开源社区在维护,质量参差不齐,而且由于是在Windows环境下,表现得很是蛋疼.比如说Eclipse下的SVN插件,我已经忘记他的名字了,但是永远都忘不了新接触他的那几天,也让我见识了Xunix下的百家齐放,这个插件可能需要依赖那个插件,而那个插件可能也需要依赖那个.如此往复.版本控制在那时是块心病,就怕哪次更新代码之后错误不断,又要重新来过.不过在几次失败的提交之后导致项目重建,大家都学乖了,要先更新,再提交.这也是一个沟通问题,这点稍后再讲.<br />
&nbsp;&nbsp; &nbsp; 2.态度问题.在项目结束的时候,还有童鞋对HTTP上的交互搞得云里雾里,还对于Session望而生畏.这些在某些培训机构几乎是只教其形而根本不教其意的东西,在他们来说会其形都有困难.打个小差,我在组中也过足了当老师的瘾,因为可以将自己当了十五年学生的经验反馈在我的教学上,好不过瘾,以前看不惯老师的某些手段,在我这里就得意充分更正.对于Session这些我通常是从HTTP无状态的这个设计着手,然后切开,继续深入,最后到为什么需要Session这个东西,在浏览器差异中也从当年的浏览器大战着手,讲的我自己都炮沫横飞,不过却过足了老师的瘾,要是老师们都能有我这样饱汉深情的讲下去何愁朽木不可雕呢?不过后面想想也是,一个老师通常要带两个甚至三个班,教育产业化,将一个东西讲重复一遍两边有可能三遍,而且一年一个循环,谁能受得了,也只有那些园丁们了.这个差有点远了,我们言归正传.在项目中,有很多自以为是的问题,这也许就是程序员们的根病吧.但是倘若没有了这股干劲,又怎样才能从无中生有,作出一个几万行的软件呢?在项目进行时,用了一些管理手段,比如一天一结,然后又是展望,<span style="background-color: rgb(255, 204, 153); ">当然计划无限好</span>(其实还有很多其他模仿着大牛们的例子,但都难以奏效,往往是东施效颦,落得个吃饱了没事干的评价),<span style="background-color: rgb(255, 204, 153); ">只是领导有些小</span>.这些规定对于童鞋们很难有实施的机会,往往他说好了今天完成的任务,其中有些自身无法估计问题大小的原因,还有确实编码能力不够的原因(我已经把模版代码写好了,这下您也懂了,他们是如何&quot;编码&quot;了的吧),可是一周之后可能问题依然没进展,最流行的词儿是&quot;基本上没问题了&quot;,&quot;快可以了&quot;,&quot;只差几个小模块(小函数)就可以了&quot;.唉,我觉得这都能让爱吹的南郭先生笑掉大牙了.<br />
&nbsp;&nbsp; &nbsp;3.项目起因问题,因为这是一个<span style="background-color: rgb(255, 204, 153); ">教学案例项目</span>,这个项目的根本目的不是在于项目是否能成,而且项目本身也只是用于申报国家们的一些&quot;计划&quot;,项目只是让童鞋们学习的,我这里就有些急功近利了,老是觉得自己不该为这样的项目编码那么多,说到底是个心里问题,不过念到自己又通过这个项目掌握了这么多,也不好说些什么,只能是说鱼与熊掌不可兼得吧,可我总觉得如果我把半年时间花在其他的地方上面可能就不是如今这样的了,话说回来谁又没有个&quot;要是当年&quot;呢.项目没有一个好的老师指导,整个进度也就凭我们几个说话没份量的童鞋约束.总而言之,言而总之.这就是一出没谱的戏儿,拿来给戏子们作秀的试验品.<br />
&nbsp;&nbsp; &nbsp;4.贪大喜新.这是我们这组的问题,在前端页面上先独自用上了ExtJS.虽然使用的时候坎坎坷坷,但的出来的效果却是大受好评,而且引得另一组前来学习,不过因为框架学习难度的原因,导致基本上就我们组两个人会用,其他童鞋只能干看着,话说项目开始的时候还是ExtJS3.0,到结束的时候发现更新到了3.1了,直接换框架发现不行,不能兼容,尝试新东西总是要付出代价的.使用ExtJS作为后端表现后,唯独第三组(我们是一组,二组后来也换这个框架了,因为界面问题,始终让人头疼)不愿意更改原来的代码,这里又有一个沟通问题,待会再说.所以导致界面风格迥异,在我们这组的时候可能是标准的ExtJS组件,一旦跳转到三组的页面时,可能就是朴素的HTML了.<br />
&nbsp;&nbsp; &nbsp;5.沟通问题.这也是最根本的问题,如果说依靠我们几个组能写代码的人,加上近半年的时间,而且项目也不是很大,如果沟通良好的话,绝对不是问题.一组擅长前台脚本,二组擅长文档,三组擅长后端编码.这不是配好了的三个桩么.可惜事与愿违.在前面定数据库的时候,<span style="background-color: rgb(255, 204, 153); ">我们都能为一个字段的存在与否争个面红耳赤</span>,在后来为了一个接口的问题还<span style="background-color: rgb(255, 204, 153); ">差点儿罢了工</span>,只能说年轻气盛,没地方发泄啊.互相也是彼此看不起彼此,觉得自己的观点和主见才是正确的.我记得最好笑的是,三组的童鞋把一些验证,以及数据之间关系的绑定都写在了一个Action里,我就指出这有悖分层,表现的逻辑都没分开,实体数据如果不是Hibernate帮忙分离下场可能是JDBC直接写到了Action中.三组的童鞋却一口咬定&quot;这是面向领域编程,和面向对象编程不同&quot;.我当时不懂什么叫&quot;面向领域&quot;,我就说&quot;我不懂什么叫领域,但总不该把这些基本的操作写到页面上去吧.&quot;他却一口咬定.我只能作罢.要是如今碰到,肯定骂他个狗血淋头,&quot;领域你妹啊,那只是一个开发模式,你妹的都把这些八杆子打不着一起的对象写在一起,以后改死你丫的.做三十年代码工人,而且次次项目都重头来过没沉淀.&quot;.唉,年轻气盛.</p>
<p>&nbsp;&nbsp; &nbsp;故事的最后,项目流产了,需求方发现同时操作的项目太多,无暇兼顾,所以就没了下文,我手抖着把项目用QQ邮箱发过去的时候,确实是勾了&quot;回信短信通知&quot;的.可能是没通知到吧.哎哟喔.....</p>
<p>&nbsp;&nbsp; &nbsp;最后是有图有真相.</p>
<p style="text-align: center; "><img onload="ResizeImage(this,520)" alt="" title="" src="http://www.macgoo.com/myblog/attachments/2010/8/201008102319340028.jpg" /><br />
首页<br type="_moz" />
&nbsp;</p>
<p style="text-align: center; "><img onload="ResizeImage(this,520)" alt="" title="" src="http://www.macgoo.com/myblog/attachments/2010/8/201008102316273307.jpg" /><br />
用户订单管理</p>
<p style="text-align: center; ">&nbsp;</p>
<p style="text-align: center; ">&nbsp;</p>
<p>&nbsp;</p>
<p style="text-align: center; "><img onload="ResizeImage(this,520)" alt="" title="" src="http://www.macgoo.com/myblog/attachments/2010/8/201008102317113824.jpg" />登录界面</p>
<p style="text-align: center; ">&nbsp;</p>
<p style="text-align: center; ">&nbsp;</p>
<p>&nbsp;</p>
<p><img onload="ResizeImage(this,520)" alt="" title="" src="http://www.macgoo.com/myblog/attachments/2010/8/201008102317557770.jpg" /><br />
&nbsp;<br />
<img onload="ResizeImage(this,520)" alt="" title="" src="http://www.macgoo.com/myblog/attachments/2010/8/201008102318255518.jpg" /></p>
<p>&nbsp;</p>
<p><img onload="ResizeImage(this,520)" alt="" title="" src="http://www.macgoo.com/myblog/attachments/2010/8/201008102318581454.jpg" /><img onload="ResizeImage(this,520)" alt="" title="" src="http://www.macgoo.com/myblog/attachments/2010/8/201008102319083116.jpg" /><img onload="ResizeImage(this,520)" alt="" title="" src="http://www.macgoo.com/myblog/attachments/2010/8/201008102320091258.jpg" /></p>
<p>&nbsp;</p>
<p><img onload="ResizeImage(this,520)" alt="" title="" src="http://www.macgoo.com/myblog/attachments/2010/8/201008102320345371.jpg" /></p>
<p>&nbsp;</p>]]></description><category>Programer</category><comments>http://www.macgoo.com/myblog/archives/153/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=153</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=153&amp;key=3310f2d7</trackback:ping></item><item><title>115网盘批量下载</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/151/</link><pubDate>Fri, 06 Aug 2010 15:10:38 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/151/</guid><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 第二段是客套,您可以忽略.第三段是说明,您可以一看.第四段是使用方法,是您大概想要的.第五段是下载连接,您最想要的.第六段是源码,您可能会有兴趣.</p>
<p>&nbsp;&nbsp;&nbsp; 如果没有115网盘,大家可能就真的少了接触这么多优秀资源的机会.所以这只是一个辅助程序,您还是要多去115网盘,多点点广告,多支持雨林木风.</p>
<p>&nbsp;&nbsp;&nbsp; 这是一个针对一个页面(或者是一段文字)含有多个115网盘下载链接自动获取真实下载路径的小工具.您可以去联系作者索要更多帮助,他目前很闲(soddyque[at]gmail.com).</p>
<p style="text-align: left;"><span style="background-color: rgb(255, 204, 0);"><span style="font-size: medium;"><span style="font-family: 黑体;">&nbsp;&nbsp;&nbsp; 使用方法:</span></span></span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: rgb(255, 0, 0);">程序需要安装 .Net Framework 3.5 才能使用</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 打开程序后,在[地址输入栏中将还有下载链接的网页的源代码粘贴到内,单击[准备]按钮就能生成连接.如图.<br />
<br />
<img title="" alt="" src="../../attachments/2010/8/201008061518364728.jpg" onload="ResizeImage(this,520)" /><img title="" alt="" src="../../attachments/2010/8/201008061518544743.jpg" onload="ResizeImage(this,520)" /><br />
<br />
&nbsp;&nbsp;&nbsp; 您当然可以选择登录您的115网盘账户后再下载,如果不登录也能同样自动获取,不过<span style="color: rgb(255, 0, 0);">一般网络繁忙的情况下只能获取的到优蛋下载连接</span>.</p>
<p style="text-align: left;"><img title="" alt="" src="../../attachments/2010/8/201008061522426331.jpg" onload="ResizeImage(this,520)" /><img title="" alt="" src="../../attachments/2010/8/201008061522524728.jpg" onload="ResizeImage(this,520)" /></p>
<p style="text-align: left;"><br />
&nbsp;&nbsp;&nbsp; 当获取完毕就能打开程序目录下的以当前时间为名的一个TXT文档,里面就是下载链接.<br />
<br />
<img title="" alt="" src="../../attachments/2010/8/201008061523122567.jpg" onload="ResizeImage(this,520)" /><br />
<br />
&nbsp;&nbsp;&nbsp; 获取到的下载链接,就能够粘贴到迅雷里去批量下载了.<br />
<br />
<img title="" alt="" src="../../attachments/2010/8/201008061523307870.jpg" onload="ResizeImage(this,520)" style="width: 481px; height: 322px;" /><br />
&nbsp;</p>
<p style="text-align: left;"><span style="background-color: rgb(255, 204, 0);"><span style="font-size: medium;"><span style="font-family: 黑体;">&nbsp;&nbsp;&nbsp; 下载地址:</span></span></span></p>
<p><a target="_blank" href="http://www.macgoo.com/myblog/attachments/2010/8/201008061518162604.zip">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 单击下载:&nbsp; 115网盘批量下载.zip</a></p>
<p>&nbsp;</p>
<p><span style="background-color: rgb(255, 204, 0);"><span style="font-size: medium;"><span style="font-family: 黑体;">&nbsp;&nbsp;&nbsp; 程序源码:</span></span></span><br />
&nbsp;&nbsp;&nbsp;&nbsp; 您可以在<a href="http://cid-bfe33abffe41e14a.office.live.com/self.aspx/CodePack/U115CarryOn.zip" target="_blank">这里</a>获取得到程序的所有代码.希望对您有用.</p>]]></description><category>Programer</category><comments>http://www.macgoo.com/myblog/archives/151/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=151</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=151&amp;key=715f96ad</trackback:ping></item><item><title>EntityFramework v1 .Net3.5 Sp1 动态查询过滤检索所遇到的问题</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/150/</link><pubDate>Fri, 23 Jul 2010 13:07:45 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/150/</guid><description><![CDATA[<p>&nbsp; &nbsp; 最近在封装EntityFramework的时候碰到许多问题,下面就做一个简短的笔记.&nbsp;</p>
<h2>&nbsp;泛型推断</h2>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 例如Save&lt;T&gt;(T  o)这样的方法是没有问题的,但是如果参数再包裹一层泛型就不行了,Save&lt;T&gt;(IEnumerable&lt;T&gt;  o),所以只能在方法体类判断是否实现了IEnumerable&lt;T&gt;接口,然后分情况处理.<a href="http://stackoverflow.com/questions/407983/c-3-0-generic-type-inference-passing-a-delegate-as-a-function-parameter" target="_blank">关于更多C#3.0中的泛型推断</a>.大体上就是说C#编译器只能推断出明确的一种类型,而不能同时包含多种,比如上面的Save&lt;T&gt;(IEnumerable&lt;T&gt; o)则编译器无法得知参数的具体类型,就需要指定类型.</p>
<h2>&nbsp;拓展方法的访问级别</h2>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 基本上就是一个外部的类,除非在同一程序集里并设定被拓展对象为internal访问级别才能访问,否则protected都访问不到.</p>
<h2>&nbsp; 封装EntityFremawork操作</h2>
<p>&nbsp; &nbsp;&nbsp; 这里主要讲讲查询,一般来说Find方法的签名如下</p>
<pre style="background-color: rgb(240, 240, 240); border: thin ridge rgb(204, 204, 204);" height="400" name="CodeLight_code" class="brush:csharp;mouse-over:#ff9">
public override List&lt;T&gt; Find&lt;T&gt;(int start, int len = 10, IWhereItem&lt;T&gt; whereitem = null, IOrderItem&lt;T&gt; orders = null, bool isDetach = true)</pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 起始元素,页长度,过滤语句,排序语句,最后一个是EntityFramework独有,是否与上下文对象解绑.<br />
&nbsp;&nbsp;&nbsp;&nbsp;  在构造ObjectQuery时就需要获得EF的映射关系,用System.Data.Metadata.Edm读取映射信息就可以了,这里我就直接将代 码贴出来了.接受一个EntityContainer就可以不断的读取信息了,本身继承一个见到那的缓存类,实际上就是对字典的一个简单封装.</p>
<pre style="background-color: rgb(240, 240, 240); border: thin ridge rgb(204, 204, 204);" height="400" name="CodeLight_code" class="brush:csharp;mouse-over:#ff9;toolbar:false">
    public class EdmInfo
    {
        public EntitySetBase EntitySetBase { get; set; }
        public string TableName { get; set; }
        public string TypeName { get; set; }
        public string KeyName { get; set; }
    }
    public class EdmInfoManager : SimpleCache&lt;Type, EdmInfo&gt;
    {
        public EntityContainer RootContainer { get; private set; }
        public EdmInfoManager(EntityContainer ec)
        {
            RootContainer = ec;
        }
        public new EdmInfo this[Type T]
        {
            get
            {
                if(!ContainsKey(T))
                {
                    EdmInfo edm = new EdmInfo();
                    edm.EntitySetBase = typeToEntitySetBase(T);
                    edm.TableName = edm.EntitySetBase.Name;
                    edm.TypeName = T.Name;
                    edm.KeyName = entitySetBaseToKeyName(edm.EntitySetBase);
                    base[T] = edm;
                    return edm;
                }
                return base[T];
            }
            set
            {
                base[T] = value;
            }
        }
        private EntitySetBase typeToEntitySetBase(Type t)
        {
            return RootContainer.BaseEntitySets
                       .Where(bes =&gt; bes.ElementType.Name == t.Name)
                       .FirstOrDefault();
        }
        private string entitySetBaseToKeyName(EntitySetBase es)
        {
            return es.ElementType.KeyMembers[0].Name;
        }
    }</pre>
<p>&nbsp;&nbsp;&nbsp;&nbsp;  然后就是排序项,由于项目有一些lambda表达式风格的排序,以及普通属性字符串似的排序,所以又做了一个简单封 装,IOrderItem&lt;T&gt;结构下有两个实现StringOrderItem与ExpressionOrderItem.主要是 StringOrderItem,因为最后都将排序信息保存为字符串了,所以只能以字符串形式排序,这就为后面造成了一些人为的障碍.<br />
&nbsp;&nbsp;&nbsp;&nbsp; 过滤项就是封装了一下Expression&lt;Func&lt;T, bool&gt;&gt;,不过提供从字符串构造的方法.最后都是Lambda表达式的形式存储.<br />
&nbsp;&nbsp;&nbsp;&nbsp; 最后检索的时候就碰到问题了,ObjectQuery.Where(Expression&lt;Func&lt;T,  bool&gt;&gt; exp)是一个拓展方法,返回的不是ObjectQuery,导致了后面无法使用OrderBy(String  orderstring).只能使用OrderBy的拓展方法Lambda表达式形式.卡壳了很久,找了一些资料.其中不乏<a href="http://code.msdn.microsoft.com/EFExtensions" target="_blank">微软的EF拓展库</a>.有个拓展方法能够强制转换为ObjectQuery在链式操作中,但是在我这里一旦强转后面的操作都报错,大概是只支持EFv4吧.</p>
<p>&nbsp; &nbsp; 能否将IWhereItem里的Lambda表达式转为ESQL语句呢?.试着重写一个ExpressionVisitor可惜没功夫没到家,表达式的资料到是找到了不少.就是没写出来.</p>
<p>&nbsp; &nbsp; 表达式的各种构造 :&nbsp;http://rednaxelafx.javaeye.com/blog/247270</p>
<p>&nbsp; &nbsp; LinqToSQL : 一种Linq到TSQL语句的转换,地址忘记了,代码在此 </p>
<p>&nbsp; &nbsp;&nbsp; 在stackoverflow的提问 :&nbsp; http://stackoverflow.com/questions/3305224/problems-with-entity-framework-queries</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 就想把Order转为Lambda表达式形式,但是如何泛型如何设置呢?Expression&lt;Func&lt;T, object&gt;&gt;在面对Expression&lt;Func&lt;T, int&gt;&gt;时会自动有个转换过程,<a href="http://stackoverflow.com/questions/3306964/lambda-expressions-automated-packing" target="_blank">详见Lambda传参自动包装</a>.所以无法直接使用Expression&lt;Func&lt;T, object&gt;&gt;类型传递,在<a href="http://www.blogfor.net/2009/09/03/dynamic-sorting-and-filtering-with-linq-to-sql/" target="_blank">动态构造Linq过滤,排序</a>时发现了一个解决方法,使用<span>IOrderedQueryable</span>包装过滤项,继续搜索,终于找到了使用泛型反射出类型,然后<a href="http://www.codeproject.com/KB/linq/IEnumerableSortByName.aspx?msg=3005452#xx3005452xx" target="_blank">动态构造Lambda表达式(且指定类型)的解决方法了</a>.</p>
<pre style="background-color: rgb(240, 240, 240); border: thin ridge rgb(204, 204, 204);" height="400" name="CodeLight_code" class="brush:csharp;mouse-over:#ff9;toolbar:false">
private static IOrderedEnumerable&lt;T&gt; SortEngine&lt;T&gt;(this IEnumerable&lt;T&gt; source, string columnName, bool isAscending, bool started)
{
    var item = Expression.Parameter(typeof(T), &quot;item&quot;);
    var propertyValue = Expression.PropertyOrField(item, columnName);
    var propertyLambda = Expression.Lambda(propertyValue, item);
    // item =&gt; item.{columnName}
    
    var sourceExpression = Expression.Parameter(typeof(IEnumerable&lt;T&gt;), &quot;source&quot;);

    string methodName;
    Expression inputExpression;
    if (started)
    {
        methodName = isAscending ? &quot;ThenBy&quot; : &quot;ThenByDescending&quot;;
        inputExpression = Expression.Convert(sourceExpression, typeof(IOrderedEnumerable&lt;T&gt;));
        // ThenBy requires input to be IOrderedEnumerable&lt;T&gt;
    }
    else
    {
        methodName = isAscending ? &quot;OrderBy&quot; : &quot;OrderByDescending&quot;;
        inputExpression = sourceExpression;
    }

    var sortTypeParameters = new Type[] { typeof(T), propertyValue.Type };
    var sortExpression = Expression.Call(typeof(Enumerable), methodName, sortTypeParameters, inputExpression, propertyLambda);
    var sortLambda = Expression.Lambda&lt;Func&lt;IEnumerable&lt;T&gt;, IOrderedEnumerable&lt;T&gt;&gt;&gt;(sortExpression, sourceExpression);
    // source =&gt; Enumerable.OrderBy&lt;T, TKey&gt;(source, item =&gt; item.{columnName})
    
    return sortLambda.Compile()(source);
}

public static IOrderedEnumerable&lt;T&gt; OrderBy&lt;T&gt;(this IEnumerable&lt;T&gt; source, string columnName)
{
    return SortEngine(source, columnName, true, false);
}

public static IOrderedEnumerable&lt;T&gt; OrderByDescending&lt;T&gt;(this IEnumerable&lt;T&gt; source, string columnName)
{
    return SortEngine(source, columnName, false, false);
}

public static IOrderedEnumerable&lt;T&gt; ThenBy&lt;T&gt;(this IOrderedEnumerable&lt;T&gt; source, string columnName)
{
    return SortEngine(source, columnName, true, true);
}

public static IOrderedEnumerable&lt;T&gt; ThenByDescending&lt;T&gt;(this IOrderedEnumerable&lt;T&gt; source, string columnName)
{
    return SortEngine(source, columnName, false, true);
}</pre>
<p>&nbsp; &nbsp; 最后Find方法全貌</p>
<pre style="background-color: rgb(240, 240, 240); border: thin ridge rgb(204, 204, 204);" height="400" name="CodeLight_code" class="brush:csharp;mouse-over:#ff9;toolbar:false">
        public override List&lt;T&gt; Find&lt;T&gt;(int start, int len = 10, IWhereItem&lt;T&gt; whereitem = null, IOrderItem&lt;T&gt; orders = null, bool isDetach = true)
        {
            var context = getInstence();
            var edminfo = EdmMgr[typeof (T)];
            ObjectQuery&lt;T&gt; query = context.CreateQuery&lt;T&gt;(&quot;[&quot; + edminfo.TableName + &quot;]&quot;);
            query = MemerVisitor.IncludeMembers.Aggregate(query, (current, str) =&gt; current.Include(str));
            orders = orders ?? OrderItemFactry.Get&lt;T&gt;(edminfo.KeyName, true);
            List&lt;T&gt; result;

            result = whereitem == null || whereitem.Body == null
                         ? start == -1
                               ? query.Skip(orders.OrderString, &quot;0&quot;).ToList()
                               : query.Skip(orders.OrderString, start.ToString()).Take(len).ToList()
                         : start == -1
                               ? query.Skip(orders.OrderString, &quot;0&quot;).Where(whereitem.Body).ToList()
                               : query.Skip(orders.OrderString, &quot;0&quot;).Where(whereitem.Body).OrderBy(orders.Property).Skip(start).Take(len).ToList();

            if (isDetach &amp;&amp; MemerVisitor.IncludeMembers.Count == 0)
                result.ForEach(x =&gt;
                                   {
                                       try
                                       {
                                           context.Detach(x);
                                       }
                                       catch (InvalidOperationException)
                                       {
                                       }
                                   });
            MemerVisitor.IncludeMembers.Clear();
            return result;
        }
</pre>]]></description><category>Programer</category><comments>http://www.macgoo.com/myblog/archives/150/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=150</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=150&amp;key=dc4262a1</trackback:ping></item><item><title>实现自己的动漫自动下载工具</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/149/</link><pubDate>Sun, 13 Jun 2010 15:43:00 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/149/</guid><description><![CDATA[<p>&nbsp;</p>
<p style="text-align: center;"><img width="500" height="357" alt="" onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/6/201006131546163714.jpg" /></p>
<p style="text-align: center;">&nbsp;</p>
<p style="text-align: left;">&nbsp; &nbsp; 目的:采集某动漫站点的动漫图片.<br />
&nbsp; &nbsp; 工具: Visual Studio 2010 / 平台: .net Freamwork&nbsp; 2.0 / WinForm</p>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;">&nbsp;&nbsp;&nbsp; 首页 -&gt; 首字母分类 -&gt; 某部动漫 -&gt; 某册 -&gt; 图片集合</p>
<p style="text-align: left;">&nbsp;&nbsp;&nbsp;&nbsp; 抓取思路就是这样,根据不同的页面构造不同的正则匹配即可.整个过程就不多说了,大家都知道.下面分享一些心得.</p>
<ol>
    <li>整个抓取过程具有相当程度的相似性<br />
    &nbsp;&nbsp;&nbsp; 每个部分流程基本上都是获取网页.然后构造 Regex 匹配出结果集合 MatchCollection 对每个匹配集合进行操作获得最终列表,然后可以递归继续操作下一页,也可以返回出与子递归相交的列表集合.<br />
    &nbsp;&nbsp;&nbsp; 所以我们就可以抽取这些相似的部分,然后将不同作为参数传入.当然,这些在后面会提到的.</li>
    <li>对于JavaScript 动态生成列表部分,进行字符串解析或者使用<a href="http://msdn.microsoft.com/zh-cn/library/microsoft.jscript(VS.80).aspx" target="_blank">微软的JScript 引擎</a>解析<br />
    &nbsp;&nbsp;&nbsp; 在我所采集的站点中,使用了JS动态输出图片地址,所以需要一些对JS文本的分析,但在这个项目中没能得到体现,只是普通的正则匹配编码后的地址,然后用翻译后的一个方法去解码.</li>
    <li>多线程调用并不麻烦<br />
    &nbsp;&nbsp;&nbsp; 可能是我使用高版本的开发环境,众所周知,在Visual Studio 2005中如果要进行一个多线程的设计,还需要更改界面显示的话是一件非常繁琐的事情,通常需要新建一个代理,然后在创建一个代理实例,然后再在线程方法中调用该实例.在VS2010中则是简单的一个Linq就可以了.极大的提高了开发效率,这让我写代码的时候都不经意得笑了起来.</li>
    <li>函数的实现多基于&quot;<a href="http://www.ocaml-tutorial.org/%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B" target="_blank">What to do</a>&quot;而尽量避免&quot;How to do&quot;<br />
    &nbsp;&nbsp;&nbsp; 这也是从函数式编程体会到的.现在不都是提倡多写测试用例吗,如果一个函数不能用代码直接断言那么只有人眼能够辨明结果是否是正确的,这是不是也太不&quot;自动&quot;了呢?<br />
    &nbsp;&nbsp;&nbsp; 比如一个读取多个分页将页面信息集合为一个结果列表的方法你是使用while循环呢还是递归调用呢?<br />
    &nbsp;&nbsp;&nbsp; while循环看似直接,但如果需要对这个函数进行测试该如何?这是一个分页列表的读取,自然将测试颗粒度放到一个页面最适合.但是递归则不同,将问题分解,将其他页面的分析递归到下一个函数去而不是下一个循环.到时候仅仅需要对特定层次的调用进行分析就可以了.</li>
    <li>字符串拼接什么时候该用 &quot;+=&quot; 什么时候该用 StringBuilder<br />
    &nbsp;&nbsp;&nbsp; 一个比较好的说明是一定次数内的拼接还是直接用 &quot;+&quot; 操作符就可以了(这里的&quot;次数有不同的说法,有说5次以内的,有说16次以内的).否则就用StringBuilder 效率比较好.<a target="_blank" href="http://www.chinhdo.com/chinh/blog/20070224/stringbuilder-is-not-always-faster/">这里有更详细的讲解</a>,<a target="_blank" href="http://www.chinhdo.com/20070929/stringbuilder-part-2/">详细2</a>.我这里只找到说5次以内的版本,以前有一张图说是16次.总之不同环境应该会有不同的表现,大家自己把握,不过字符串拼接应该不会成为性能瓶颈.所以这一点点吹毛求疵就留给<a target="_blank" href="http://www.macgoo.com/myblog">米落</a>自己把玩吧~</li>
</ol>
<p>&nbsp;&nbsp;&nbsp; 项目不是很OO,所有方法都写在了一个Form窗体类里,这在后面会进行一些设计的.写这个东西花了几个钟头,没有太多的精力,下周还有期末考试和CET4,还有一个微软之星的比赛,总感觉自己像个事儿逼,就爱瞎鼓捣...唉抱怨的话就不多说了.各位自己看吧.</p>
<p>&nbsp;&nbsp;&nbsp; <a target="_blank" href="http://cid-bfe33abffe41e14a.office.live.com/self.aspx/CodePack/BuiltComic.zip">代码下载</a></p>
<p style="text-align: left;"><br />
<br />
&nbsp;</p>]]></description><category>Programer</category><comments>http://www.macgoo.com/myblog/archives/149/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=149</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=149&amp;key=145bdfd7</trackback:ping></item><item><title>QQ微博自动收听用户</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/148/</link><pubDate>Mon, 31 May 2010 11:54:22 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/148/</guid><description><![CDATA[<p>
<link href="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Styles/shCore.css" rel="stylesheet" type="text/css" />
<link href="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Styles/shThemeDefault.css" rel="stylesheet" type="text/css" /><script language="javascript" src="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/shCore.js"></script><script language="javascript" src="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/shBrushCSharp.js"></script></p>
<p style="text-align: center;"><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/5/201005311242228863.jpg" alt="" title="" /></p>
<p>&nbsp;&nbsp;&nbsp; 闲来无聊,一上午鼓捣点东西.<br />
&nbsp;&nbsp;&nbsp; 自从开通了腾讯微博后希望找找有些出彩的地方,人口基数大就是人口基数大,许多牛人都能出口惊人,可是收听其他用户得一个一个的点,费时费力,于是我就写了个自动添加的偷偷懒.</p>
<p>&nbsp;&nbsp;&nbsp; 登录后获取cookie然后获取自身好友,然后获取每个好友列表,并且查询可以收听的用户(可以判断只添加认证用户),再发出收听请求.Over.简单吧.下面详细分析.</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 1.登录,我这里用的是WebBrowser,设置URI为 http://t.qq.com/ ,就好了<br />
&nbsp;&nbsp;&nbsp; 2.string2CookieContainer,登录后的WebBrowser对象保存着cookie,这是验证请求是否有效的唯一凭据,所以要保存好了(<a target="_blank" href="http://baike.baidu.com/view/835.htm">更多关于Cookie</a>),后面我们将会使用一个HttpHelper小工具类负责数据交互,他的构造函数包括几个重载形式,其中一个接受CookieContainer 为请求提供凭据.但是WebBrowser里保存的是文本形式,所以我写了一个简单的转换:</p>
<pre class="brush:csharp;mouse-over:#ff9" name="CodeLight_code" height="400" style="background-color: rgb(240, 240, 240); border: thin ridge rgb(204, 204, 204);">
        public static CookieContainer Str2CC(string cookie, Uri uri)
        {
            CookieContainer cc = new CookieContainer();
            string[] temps = cookie.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string str in temps)
            {
                string name = str.Substring(0, str.IndexOf(&quot;=&quot;)).Trim();
                string value = str.Substring(str.IndexOf(&quot;=&quot;) + 1).Trim();
                Cookie c = new Cookie(name, value);
                cc.Add(uri, c);
            }
            return cc;
        }</pre>
<p>&nbsp;&nbsp;&nbsp; 以后的数据交互都通过HttpHelper来进行.</p>
<p>&nbsp;&nbsp;&nbsp; 3.匹配所有好友.<br />
&nbsp;&nbsp;&nbsp; 正则查找出了用户的连接,已经用户名称,并且还补货了一个是否认证的标志,这些在后面的请求中都将会用到的.</p>
<pre class="brush:csharp;mouse-over:#ff9" name="CodeLight_code" height="400" style="background-color: rgb(240, 240, 240); border: thin ridge rgb(204, 204, 204);">
private Regex rg = new Regex(@&quot;&lt;strong&gt;&lt;a href=&quot;&quot;(.+?)&quot;&quot; title=&quot;&quot;.+?\(@(.+?)\)&quot;&quot;&gt;.+?&lt;/a&gt;(&lt;a href=&quot;&quot;/certification&quot;&quot; title=&quot;&quot;腾讯认证&quot;&quot; target=&quot;&quot;_blank&quot;&quot; class=&quot;&quot;vip&quot;&quot;&gt;&lt;/a&gt;)?&lt;/strong&gt;&quot;, RegexOptions.Multiline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
</pre>
<p>&nbsp;&nbsp;&nbsp; 4.发出请求.<br />
&nbsp;&nbsp;&nbsp; 分析了一下QQ微博的收听请求,向 http://t.qq.com/follow.php 发出一个请求,包含两个参数 u 和 r. u是用户名称, r为一个随机数.返回结果为成功,或者今日收听人数上线,我就收到了这两个反馈.</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 部分代码:</p>
<p>&nbsp;</p>
<p style="text-align: center;"><img onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2010/5/201005311233060638.jpg" alt="" title="" /></p>
<script language="javascript">SyntaxHighlighter.config.clipboardSwf = 'http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/clipboard.swf';SyntaxHighlighter.all();</script>]]></description><category>Programer</category><comments>http://www.macgoo.com/myblog/archives/148/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=148</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=148&amp;key=ac5ec54c</trackback:ping></item><item><title>腾讯微博邀请码(5.30更新)</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/147/</link><pubDate>Tue, 25 May 2010 13:35:37 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/147/</guid><description><![CDATA[<p style="text-align: center;"><img src="http://www.macgoo.com/myblog/attachments/2010/5/201005251338298373.jpg" title="" alt="" onload="ResizeImage(this,520)" /></p>
<p style="text-align: center;">&nbsp;</p>
<p style="text-align: left;">&nbsp;&nbsp;&nbsp; 偶然得到了一个邀请码,试用了几天,作为国内用户基数最大的腾讯,不愁卖不出去的产品啊,比起新浪的明星战略,腾讯的草根战略应该更适合中国网民吧,还有人比腾讯还了解中国用户心理?分级制度严密,任何一种产品有了QQ的绑定,就不愁吃穿了.下面是五个邀请码,送给有需要的人.</p>
<p style="text-align: left;">&nbsp;</p>
<pre style="background-color: rgb(240, 240, 240); border: thin ridge rgb(204, 204, 204);" height="400" class="brush:xml;mouse-over:#ff9">
================5.30更新邀请码======================
<a href="http://t.qq.com/invite/956f9c5d1c7c3ad5eff5"  target="_blank">http://t.qq.com/invite/956f9c5d1c7c3ad5eff5</a>
<a href="http://t.qq.com/invite/7f51fce062361bf639ef"  target="_blank">http://t.qq.com/invite/7f51fce062361bf639ef</a>
<a href="http://t.qq.com/invite/c3a1099551dc701acb93"  target="_blank">http://t.qq.com/invite/c3a1099551dc701acb93</a>
<a href="http://t.qq.com/invite/1ad951dbfdf3277e0a37"  target="_blank">http://t.qq.com/invite/1ad951dbfdf3277e0a37</a>

================5.28更新邀请码======================
<a href="http://t.qq.com/invite/8079db47214f681844cd"  target="_blank">http://t.qq.com/invite/8079db47214f681844cd</a>
<a href="http://t.qq.com/invite/956f9c5d1c7c3ad5eff5"  target="_blank">http://t.qq.com/invite/956f9c5d1c7c3ad5eff5</a>
<a href="http://t.qq.com/invite/7f51fce062361bf639ef"  target="_blank">http://t.qq.com/invite/7f51fce062361bf639ef</a>
<a href="http://t.qq.com/invite/c3a1099551dc701acb93"  target="_blank">http://t.qq.com/invite/c3a1099551dc701acb93</a>
<a href="http://t.qq.com/invite/1ad951dbfdf3277e0a37"  target="_blank">http://t.qq.com/invite/1ad951dbfdf3277e0a37</a>

=================以下邀请码已被注册==================
<a href="http://t.qq.com/invite/b760eb08756dcc802707"  target="_blank">http://t.qq.com/invite/b760eb08756dcc802707</a>
<a href="http://t.qq.com/invite/6be6f848b58dad070589"  target="_blank">http://t.qq.com/invite/6be6f848b58dad070589</a>
<a href="http://t.qq.com/invite/f1c59d29a8f535feea6d"  target="_blank">http://t.qq.com/invite/f1c59d29a8f535feea6d</a>
<a href="http://t.qq.com/invite/5465d7731a6c1685e84f"  target="_blank">http://t.qq.com/invite/5465d7731a6c1685e84f</a>
<a href="http://t.qq.com/invite/1c8ccc56bddf26a7953b"  target="_blank">http://t.qq.com/invite/1c8ccc56bddf26a7953b</a>
</pre>
<p>&nbsp;</p>]]></description><category>Booooer.</category><comments>http://www.macgoo.com/myblog/archives/147/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=147</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=147&amp;key=4fe2234e</trackback:ping></item></channel></rss>
