<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_CoolCode</title><subtitle type="text">编程的艺术世界曾经是一个只懂得绘画艺术的我,如今追求编程的艺术.</subtitle><id>http://feed.cnblogs.com/blog/u/50790/rss</id><updated>2012-02-11T04:45:18Z</updated><author><name>CoolCode</name><uri>http://www.cnblogs.com/coolcode/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/coolcode/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/50790/rss"/><entry><id>http://www.cnblogs.com/coolcode/archive/2011/06/16/godhorse_programmer.html</id><title type="text">教你如何成为一名不合格的程序员</title><summary type="text">本文教你如何成为一名不合格的程序员，已经成为或即将成为或具有该潜质的童鞋可以看看，复习一下，也请不吝赐教。其他的认为一辈子都无法达到这种境界的童鞋，可以以此文作为茶余饭后的笑料。1. 永远要两次跳进同一个坑里。2. 让你的Leader重复他/她说过的话。</summary><published>2011-06-16T14:57:00Z</published><updated>2011-06-16T14:57:00Z</updated><author><name>CoolCode</name><uri>http://www.cnblogs.com/coolcode/</uri></author><link rel="alternate" href="http://www.cnblogs.com/coolcode/archive/2011/06/16/godhorse_programmer.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/coolcode/archive/2011/06/16/godhorse_programmer.html"/><content type="html">&lt;p&gt;&lt;/p&gt; &lt;p&gt;本文教你如何成为一名不合格的程序员，已经成为或即将成为或具有该潜质的童鞋可以看看，复习一下，也请不吝赐教。其他的认为一辈子都无法达到这种境界的童鞋，可以以此文作为茶余饭后的笑料。&lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none"  alt="太棒了" src="http://images.cnblogs.com/cnblogs_com/coolcode/201106/201106162256338348.png"&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;1. 永远要两次跳进同一个坑里。&lt;/p&gt; &lt;p&gt;2. 让你的Leader重复他/她说过的话。&lt;/p&gt; &lt;p&gt;3. 每件事情只做好一半，但要跟Leader说：差不多了。&lt;/p&gt; &lt;p&gt;4. 永远不要对自己做过的事负责。&lt;/p&gt; &lt;p&gt;5. 要写出连自己都看不懂的代码，这样才显得自己与众不同。&lt;/p&gt; &lt;p&gt;6. 编码规范神马的都是浮云，哥的代码才是标准：变量名用abc，方法名大小写等都是即兴表演。&lt;/p&gt; &lt;p&gt;7. 不管什么问题绝对不要跟Leader说，以免他/她知道你的不足。&lt;/p&gt; &lt;p&gt;8. 你的编程知识已经可以应付一切项目了，啥学习或培训都不用啦，空余时间泡妞玩游戏已经够累啦。&lt;/p&gt; &lt;p&gt;9. 多犯一些低级错误，反正Leader也是闲着没事干，让他/她看看我的“杰作”刺激一下神经多好啊，不是吗？&lt;/p&gt; &lt;p&gt;10. 如果运气不好不小心参加了公司的开发培训，在课堂上左耳进右耳出就可以了，然后在开发过程中不断去提问吧。&lt;/p&gt; &lt;p&gt;11. 像神父传教一样多向周围的程序员宣传“技术无用论”。&lt;/p&gt; &lt;p&gt;12. 上班时间打打酱油，下班时间加加班，这是必须的！&lt;/p&gt; &lt;p&gt;13. 干完一项任务别告诉Leader，一旦让他/她知道就会分配其他任务来的。&lt;/p&gt; &lt;p&gt;14. 拿着一个锤子干活就足够了，其他神马的都是钉子而已。&lt;/p&gt; &lt;p&gt;15. 别去看人家的博客，甭管它有多优秀；买书籍？又不能当饭吃！等有问题，在论坛上发帖跪求就KO了。&lt;/p&gt; &lt;p&gt;16. 你不会写的代码都是因为Leader没有提供一个可以供你Copy的版本而已。&lt;/p&gt; &lt;p&gt;17. 提交一些不能编译的代码到代码服务器吧，很有趣的。&lt;/p&gt; &lt;p&gt;18. 注释是多余的。&lt;/p&gt; &lt;p&gt;19. 未来想做项目经理，所以不用学技术，开发前不用搞什么计划，开发后也不用总结。&lt;/p&gt; &lt;p&gt;20. 多信信什么什么哥之类的，他能让你原地复活，挂几次也不怕，就是不要常挂在一个公司上。&lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none"  alt="吐舌笑脸" src="http://images.cnblogs.com/cnblogs_com/coolcode/201106/201106162256339776.png"&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/coolcode/aggbug/2083164.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/coolcode/archive/2011/06/16/godhorse_programmer.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/coolcode/archive/2011/06/08/IQueryBuilder_v2.html</id><title type="text">QueryBuilder ： 打造优雅的Linq To SQL动态查询(支持EF、.Net4)</title><summary type="text">大概两年前我写了篇《QueryBuilder ： 打造优雅的Linq To SQL动态查询》，赢得不少厚爱，如今它还是我博客访问量最高的一篇（即使只有可怜的5500点击量，比一些大牛们少一位数）。时过境迁、岁月不饶人，当年得意之作现在看起来不值一文。收集一下朋友的反馈，主要有下列问题：不支持 Entity Framework不支持.Net 4Equals(c=&gt;c.xx, null) 之前是被忽略掉，实际上应该解析成 c.xx is null。Between 没有考虑字符串的情况，例如 Between(c=&gt;c.xx, ”A” , ”Z”) 则解析会报错。部分不支持Nullable类型其他没实现的功能：大于、小于、或…——现在——QueryBuilder已经发生翻天覆地的变化，但对于使用者来说，使用接口还是一成不变的，并且完全兼容上一版本。当然，它依旧是开源&amp;免费的！</summary><published>2011-06-08T13:58:00Z</published><updated>2011-06-08T13:58:00Z</updated><author><name>CoolCode</name><uri>http://www.cnblogs.com/coolcode/</uri></author><link rel="alternate" href="http://www.cnblogs.com/coolcode/archive/2011/06/08/IQueryBuilder_v2.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/coolcode/archive/2011/06/08/IQueryBuilder_v2.html"/><content type="html">&lt;p&gt;大概两年前我写了篇《&lt;a href="http://www.cnblogs.com/coolcode/archive/2009/09/28/IQueryBuilder.html" target="_blank"&gt;QueryBuilder ： 打造优雅的Linq To SQL动态查询&lt;/a&gt;》，赢得不少厚爱，如今它还是我博客访问量最高的一篇（即使只有可怜的5500点击量，比一些大牛们少一位数）。时过境迁、岁月不饶人，当年得意之作现在看起来不值一文。收集一下朋友的反馈，主要有下列问题：&lt;/p&gt; &lt;ol&gt; &lt;ol&gt; &lt;li&gt;不支持 Entity Framework&lt;/li&gt; &lt;li&gt;不支持.Net 4&lt;/li&gt; &lt;li&gt;Equals(c=&amp;gt;c.xx, null) 之前是被忽略掉，实际上应该解析成 c.xx is null。&lt;/li&gt; &lt;li&gt;Between 没有考虑字符串的情况，例如 Between(c=&amp;gt;c.xx, ”A” , ”Z”) 则解析会报错。&lt;/li&gt; &lt;li&gt;部分不支持Nullable类型&lt;/li&gt; &lt;li&gt;其他没实现的功能：大于、小于、或…&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="5"&gt;——现在——&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;QueryBuilder已经发生翻天覆地的变化，但对于使用者来说，使用接口还是一成不变的，并且完全兼容上一版本。当然，它依旧是开源&amp;amp;免费的！&lt;/p&gt; &lt;p&gt;&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;queryBuilder = &lt;span style="color: #2b91af"&gt;QueryBuilder&lt;/span&gt;.Create&amp;lt;&lt;span style="color: #2b91af"&gt;Orders&lt;/span&gt;&amp;gt;()&#xD;
    .Like(c =&amp;gt; c.Customers.ContactName, txtCustomer.Text)&#xD;
    .Like(c =&amp;gt; c.Customers.CompanyName, txtCustomer.Text)&#xD;
    .Between(c =&amp;gt; c.OrderDate, &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Parse(txtDateFrom.Text), &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Parse(txtDateTo.Text))&#xD;
    .Equals(c =&amp;gt; c.EmployeeID, &lt;span style="color: blue"&gt;int&lt;/span&gt;.Parse(ddlEmployee.SelectedValue))&lt;span style="color: green"&gt;&#xD;
    &lt;/span&gt;.In(c =&amp;gt; c.ShipCountry, selectedCountries);&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;技术分析&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;Lambda表达式的参数作用域&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;难点在于不同查询条件之间的参数作用域是相对独立的，如果直接使用 Expression.AndAlso来拼接是行不通的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/coolcode/201106/201106082150089216.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/coolcode/201106/201106082150148588.png" width="776" height="100"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;上一版本用Expression.Invoke解决，但Invoke在EF下不支持。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/coolcode/201106/201106082150166471.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/coolcode/201106/201106082150254467.png" width="949" height="177"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;解决办法是改用 &lt;a href="http://msdn.microsoft.com/zh-cn/library/system.linq.expressions.expressionvisitor.aspx" target="_blank"&gt;ExpressionVisitor&lt;/a&gt;，重写VisitParameter，返回新的参数表达式。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParameterExpressionVisitor &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;ExpressionVisitor&#xD;
&lt;/span&gt;{&#xD;
    &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParameterExpression &lt;/span&gt;newParameterExpression;&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;ParameterExpressionVisitor(&lt;span style="color: #2b91af"&gt;ParameterExpression &lt;/span&gt;p)&#xD;
    {&#xD;
        newParameterExpression = p;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression &lt;/span&gt;ChangeParameter(&lt;span style="color: #2b91af"&gt;Expression &lt;/span&gt;exp)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;Visit(exp);&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;protected override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression &lt;/span&gt;VisitParameter(&lt;span style="color: #2b91af"&gt;ParameterExpression &lt;/span&gt;p)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;newParameterExpression;&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;也即是获取第一个Lambda表达式的参数，把后面的表达式用该参数替换。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression &lt;/span&gt;GetMemberExpression&amp;lt;T, P&amp;gt;(&lt;span style="color: #2b91af"&gt;IQueryBuilder&lt;/span&gt;&amp;lt;T&amp;gt; q, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, P&amp;gt;&amp;gt; property)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(q.Parameters == &lt;span style="color: blue"&gt;null &lt;/span&gt;|| q.Parameters.Length == 0)&#xD;
    {&#xD;
        q.Parameters = property.GetParameters();&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;property.Body;&#xD;
    }&#xD;
     &#xD;
    &lt;span style="color: #2b91af"&gt;ParameterExpressionVisitor &lt;/span&gt;visitor =&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ParameterExpressionVisitor&lt;/span&gt;(q.Parameters[0]);&#xD;
&#xD;
    &lt;span style="color: #2b91af"&gt;Expression &lt;/span&gt;memberExpr = visitor.ChangeParameter(property.Body);&#xD;
&#xD;
    &lt;span style="color: blue"&gt;return &lt;/span&gt;memberExpr;&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;In操作&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;旧版本的In操作不支持EF，改成通过反射获取泛型方法。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;pre &gt;……&#xD;
       &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;P[], P, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; InExpression = (list, el) =&amp;gt; list.Contains(el);&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;methodExp = InExpression;&#xD;
       &lt;strike&gt; &lt;span style="color: blue"&gt;var &lt;/span&gt;invoke = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Invoke(methodExp, constant, property.Body);&lt;/strike&gt;&#xD;
        &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; lambda = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Lambda&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt;(invoke, parameter);&#xD;
……&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;其中有重载的泛型方法的获取比较麻烦，大家可以观摩一下代码，看看有无好建议。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;pre &gt;&lt;span style="color: green"&gt;//var method = typeof(Enumerable).GetMethod("Contains");  //因为有重载，这样获取不到&#xD;
&lt;/span&gt;&lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MethodInfo &lt;/span&gt;method_Contains =&#xD;
                (&lt;span style="color: blue"&gt;from &lt;/span&gt;m &lt;span style="color: blue"&gt;in typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Enumerable&lt;/span&gt;).GetMethods()&#xD;
                 &lt;span style="color: blue"&gt;where &lt;/span&gt;m.Name.Equals(&lt;span style="color: #a31515"&gt;"Contains"&lt;/span&gt;)&#xD;
                     &amp;amp;&amp;amp; m.IsGenericMethod&#xD;
                     &amp;amp;&amp;amp; m.GetGenericArguments().Length == 1&#xD;
                     &amp;amp;&amp;amp; m.GetParameters().Length == 2&#xD;
                 &lt;span style="color: blue"&gt;select &lt;/span&gt;m&#xD;
                ).First();&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;Like操作&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;旧版本的Like操作使用SqlMethods.Like，也不支持EF。新版本改成字符串的Contains。&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;).GetMethod(&lt;span style="color: #a31515"&gt;"Contains"&lt;/span&gt;, &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;[] { &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;) })&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;Between操作&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;旧版本的Between不支持字符串，例如 Between(c=&amp;gt;c.xx, ”A” , ”Z”) 则解析会报错。新版本增加新的扩展方法单独处理字符串的情况。&lt;/p&gt;&#xD;
&lt;pre &gt;Between&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IQueryBuilder&lt;/span&gt;&amp;lt;T&amp;gt; q, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;&amp;gt; property, &lt;span style="color: blue"&gt;string &lt;/span&gt;from, &lt;span style="color: blue"&gt;string &lt;/span&gt;to)&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;小结&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;很难得两年写的东东在今时今日还能保持原有接口不变并成功重构啊，已经激动到内牛满面&amp;amp;裸奔ing…&lt;/p&gt;&#xD;
&lt;p&gt;源代码下载 &lt;a href="http://files.cnblogs.com/coolcode/CoolCode.Linq.V2.rar"&gt;CoolCode.Linq.V2.rar&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;参考&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a title="http://www.cnblogs.com/coolcode/archive/2009/09/28/IQueryBuilder.html" href="http://www.cnblogs.com/coolcode/archive/2009/09/28/IQueryBuilder.html"&gt;http://www.cnblogs.com/coolcode/archive/2009/09/28/IQueryBuilder.html&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/coolcode/aggbug/2075749.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/coolcode/archive/2011/06/08/IQueryBuilder_v2.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/coolcode/archive/2011/05/17/from_baby_to_project_management.html</id><title type="text">从换纸尿片到项目管理</title><summary type="text">温馨提示暂无小孩的朋友等将来有小孩后再来看这篇文章会更有意思。感想今日换纸尿片突发奇想，激发项目管理的灵感，兴高采烈，赶紧磨墨写文，存此流芳百世。</summary><published>2011-05-16T17:54:00Z</published><updated>2011-05-16T17:54:00Z</updated><author><name>CoolCode</name><uri>http://www.cnblogs.com/coolcode/</uri></author><link rel="alternate" href="http://www.cnblogs.com/coolcode/archive/2011/05/17/from_baby_to_project_management.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/coolcode/archive/2011/05/17/from_baby_to_project_management.html"/><content type="html">&lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://www.jiangkang365.cn/uploadfile/200905/8/00115426486.jpg" width="400" height="345"&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;客户&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;小霸王（闺女的别称），出生10天。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;原始需求&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;为小霸王换纸尿片。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;需求细化&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;换纸尿片，擦干净屁股，不能着凉，舒服。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;客户满意度&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;小霸王不哭，屁股要干净。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;项目角色&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;在前几个项目，我都是担任助理工程师，如在换尿片项目中端水、拿垃圾桶等细活。但由于参与整个项目过程，慢慢领会项目各阶段的奥秘，立马晋升成项目经理，现已成功实施3个项目经验，也是客户满意度最高的几个。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;约束条件&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;小霸王怕冻；不懂技术语言，只会发3个音——咿呀哇。无法把握客户需求有一部分原因是，当她哇哇叫时，是要换尿片呢还是要喝奶呢。因为对于客户看来，换尿片和喝奶都是同一样东西，因此她表达都一样，需要不断细化才能准确把握真正的需求点。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;项目风险&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;预估项目风险有利于降低项目风险。换尿片的风险其一是小霸王容易着凉，会导致整个项目失败，是最高风险；其二是换纸尿片时，小霸王的黄金可能会漏出来，导致项目成本增加——拖地。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;项目启动会&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;小霸王叫了，确认换尿片角色——我担任项目经理，兼项目实施；小霸王妈妈担任高级换尿片工程师。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;团队激励&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;换纸尿片项目是客户面前最关注的一个项目，成功实施会向全省BB推广。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;项目估算&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;工作量：2人8分钟；资源：2人、取暖器、爽身粉、盆子、暖水、垃圾桶、纸尿片、毛巾、手帕（擦屁股用）。专家评估法：关羽阿妈评估5分钟、刘备阿妈评估9分钟、张飞阿妈评估10分钟，最后汇总得出结果是8分钟。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;需求分析&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;小霸王怕冷，要关好窗户，开取暖器以防着凉。擦屁股在保证擦干净的前提下，力度得适中，擦的舒服。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;技术准备&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;准备取暖器、爽身粉、暖水、垃圾桶、纸尿片，关好窗户，并精通尿片使用指南。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;项目设计&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;关窗，取暖器温度适中，暖水接近体温。脱小霸王的裤子、原纸尿片放入垃圾桶，用暖水擦屁股，用毛巾擦干，刷爽身粉，换上新的纸尿片，穿裤子，关暖气、开窗，清理现场。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;项目实施&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;按设计流程和要求实施，并增加环节：在整个换尿片过程，用各种办法分散小霸王的注意力。如果实施过程不合客户的要求，她会发飙，哇哇乱叫——老爸！你手脚还不快点，想要我的小命是不？！&lt;/p&gt; &lt;p&gt;&lt;strong&gt;团队协作&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;小霸王妈妈抽掉旧尿片后，反馈并说明可以进行擦屁股流程。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;客户验收&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;小霸王愉快地睡觉。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;项目总结&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;这个换尿片项目等到客户的一致好评，准确把握客户需求，成功控制取暖器的温度和擦屁股的力度。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;过程改进&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;降低成本，如在保证小霸王舒适度的前提下减少纸尿片的支出；提高效率：减少换尿片的时间。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;团队建设&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;提高团队协作能力，换纸尿片各环节的配合；提高工作效率，快速地帮小霸王宽衣穿衣。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;知识库管理&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;项目成员总结项目经验并且文档化，启动新成员。如本文。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;产品化&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;出书《高效换尿片的45个习惯》、《走出换尿片的作坊》，开发换尿片机器人等。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;温馨提示&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;暂无小孩的朋友等将来有小孩后再来看这篇文章会更有意思。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;感想&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;今日换纸尿片突发奇想，激发项目管理的灵感，兴高采烈，赶紧磨墨写文，存此流芳百世。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/coolcode/aggbug/2048305.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/coolcode/archive/2011/05/17/from_baby_to_project_management.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/coolcode/archive/2011/05/13/lower_management.html</id><title type="text">基层管理杂谈</title><summary type="text">几乎每种行业都有基层主管（或基层管理人员），而软件行业的基层主管一般是项目经理、技术经理、开发经理、组长等。其职责是资源协调、风险预估、项目管控、团队建设，说白一点大多数的企业现状就是项目负责人带领团队攻下一个又一个项目的过程。很多公司以项目成败作为项目负责人考核的唯一标准，因为项目规模、成本、客户满意度等容易量化，并且是直接跟公司的利润有很大关系；而相反团队建设却难以衡量，如何衡量一个普通技工晋升成高级技工到底是基层主管的培养还是原员工本身就具备高级技工的技能。因此，难免出现以项目额度论英雄的局面，这样往往造成一将功成万骨枯的悲壮场面，并不利于团队的发展。卡耐基曾经说过，带走我的员工，把我的工厂留下，不久后工厂就会长满杂草；拿走我的工厂，把我的员工留下，不久后我们还会有个更好的工厂。我的观点是，从短期目标来看，项目成功是解决温饱问题的指标，如果温饱问题未解决，还如何谈吃得好，如团队经常疯狂加班赶项目就是温饱尚未解决的一种表现；从长远角度来看，团队建设是迈向“吃得好”的改进过程，或着说是一种手段。</summary><published>2011-05-12T17:27:00Z</published><updated>2011-05-12T17:27:00Z</updated><author><name>CoolCode</name><uri>http://www.cnblogs.com/coolcode/</uri></author><link rel="alternate" href="http://www.cnblogs.com/coolcode/archive/2011/05/13/lower_management.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/coolcode/archive/2011/05/13/lower_management.html"/><content type="html">&lt;p&gt;几乎每种行业都有基层主管（或基层管理人员），而软件行业的基层主管一般是项目经理、技术经理、开发经理、组长等。其职责是资源协调、风险预估、项目管控、团队建设，说白一点大多数的企业现状就是项目负责人带领团队攻下一个又一个项目的过程。很多公司以项目成败作为项目负责人考核的唯一标准，因为项目规模、成本、客户满意度等容易量化，并且是直接跟公司的利润有很大关系；而相反团队建设却难以衡量，如何衡量一个普通技工晋升成高级技工到底是基层主管的培养还是原员工本身就具备高级技工的技能。因此，难免出现以项目额度论英雄的局面，这样往往造成一将功成万骨枯的悲壮场面，并不利于团队的发展。卡耐基曾经说过，带走我的员工，把我的工厂留下，不久后工厂就会长满杂草；拿走我的工厂，把我的员工留下，不久后我们还会有个更好的工厂。我的观点是，从短期目标来看，项目成功是解决温饱问题的指标，如果温饱问题未解决，还如何谈吃得好，如团队经常疯狂加班赶项目就是温饱尚未解决的一种表现；从长远角度来看，团队建设是迈向“吃得好”的改进过程，或着说是一种手段。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;一只狮子带领一群绵羊的团队会战胜由一只绵羊带领一群狮子的团队&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;如果你是一只绵羊，配备一群狮子般的团队也是枉然。说到这里，我曾经从一个电视节目看到十多只年轻狮子攻击一头河马，由于缺乏领队，结果导致河马成功逃过一劫并且一头狮子牺牲这样难以置信的场面。后来，同样这群狮子在一只经验丰富的狮子带领下，战胜比河马更强壮更凶猛的对手。&lt;/p&gt; &lt;p&gt;基层主管往往来自基层的优秀员工，在成功转型之前必须先把自己的宝剑磨利。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;在NBA赛场上，5个科比组成的球队可能会输给联盟任何一只球队&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;一个项目一般需要若干个成员组成团队——售前、需求、设计、开发、测试、部署等。而现实情况往往是，要么项目急、要么人员未到位，或者两种情况都有，那么开发人员由于在公司所占比例大，可能会兼做需求和测试。这样造成的后果是，需求把握不明确，测试不到位导致软件质量差，客户不断投诉。&lt;/p&gt; &lt;p&gt;正如下象棋一样，必须了解各种棋子的角色和作用，以及它们应该摆放的位置。否则拿车当兵使，后果可想而知。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;当项目出现危机，基层主管的第一反应是？&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;如果第一反应是“这个问题是哪个兔崽子造成的”，意味着该主管的思维是先追究责任。有一次，需要向客户演示现有的开发成果，由于各种原因导致离演示的前一天发现很多功能都未完善，如果照这样演示给客户看的话简直是演猴戏。当时，基层主管唯有向上汇报，而高级主管的第一反应是，评估完善这些功能需要多少时间？现在增加资源是否能够缩短工期？需要哪些资源才能完成？并且在该项目所有成员目前表示，他不想追究任何一个人的错误，首要任务是先分析如何能够解决问题。事后，他再向基层主管了解如何改进才能避免同类问题的发生，通过这种方式相当于给基层主管上了一次深刻的管理课程。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;聆听团队的意见&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;善于聆听是良好沟通的铺垫。如果你的团队成员在他岗位上老老实实的干了几个月，突然他有一天告诉你（或者从其他成员了解到），他觉得自己的工作没意思。这其实不完全是分工的问题，很大程度上是沟通出现问题。试问，他是觉得没意思，而不是不合适，即他胜任这份工作，可惜觉得缺少了什么，可能是缺少锻炼机会、想换个项目等等。主动去了解团队成员的意向，因为把他们放在感兴趣的岗位会发挥他们潜在的能力。当然并不是每个人都能找到适合自己的岗位，恰当的给予激励会鼓舞士气，保持工作的热情。某些基层主管把开空头支票当激励，结果失信于团队。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;最大限度地发挥团队的力量是每个基层主管的职责&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;最大限度地发挥团队的力量的前提是得深入了解每个团队成员的技能和喜好。特别是软件工程师，很多不善于语言表达也不会表现自己，更多的需要基层主管去观察。如A君喜欢钻研技术但是缺乏经验，如果有技术难度较高地先分配给他，帮他分析解决方案，更重要的是给他信心。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;不要说我以为&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;基层主管不同于普通员工，一旦犯错就勇于承担。如果说“我以为…，想不到会…，结果造成…”，是一种借口，是不成熟的表现。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;让团队主动反馈&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;基层主管要了解他管理的不是一群机器，是一支优秀的队伍。如果把团队训练成机器，最终会累死基层主管。例如，你需要挨个挨个的去问他们工作进展的怎么样，或者索性让他们写日报周报来反馈。这样得到的结果就是一切看起来很美好，而实际情况就可能隐藏一个个定时炸弹。如果并非团队成员的主动反馈，“被反馈”往往是走走形式，例如某某说“A功能完成了，B功能差不多了”。到了第二天、第三天还是“B功能差不多了”。主动反馈是简要说说工作的问题和解决方法，如某某说“A功能解决方案是…，B功能遇到…问题，C功能预计明天可完成”，并且更重要的是，不是等到你去问他才反馈。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;以上纯粹是自己对基层管理的个人看法，也是自己一些微薄经验的一个小结，思维有点混乱。这里抛砖引玉，希望听到更多的建议。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/coolcode/aggbug/2045028.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/coolcode/archive/2011/05/13/lower_management.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/coolcode/archive/2011/03/15/recruit_and_employ.html</id><title type="text">面试者与面试官</title><summary type="text">作为初入职场，特别是对于刚踏入社会的热血青年，其实很希望，即使是得到那么一丁点的指引，也足以让他们少奋斗一段历程。作为过来人，我为那些工作一两年仍然停留学生阶段的朋友感到惋惜，与其勉强为了专业对口而从事自己不擅长的工作，倒不如索性转行来得痛快。</summary><published>2011-03-15T14:45:00Z</published><updated>2011-03-15T14:45:00Z</updated><author><name>CoolCode</name><uri>http://www.cnblogs.com/coolcode/</uri></author><link rel="alternate" href="http://www.cnblogs.com/coolcode/archive/2011/03/15/recruit_and_employ.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/coolcode/archive/2011/03/15/recruit_and_employ.html"/><content type="html">&lt;p&gt;&lt;/p&gt; &lt;p&gt;目前公司挺缺人才，其实一直都缺。一个多星期下来，我面试了不少开发人员，他们的表现实在不敢恭维。想起一年前这个时候，作为应聘者的我再怎么逊也不至于这样，一年前的面试故事请&lt;a href="http://www.cnblogs.com/coolcode/archive/2010/04/01/1702570.html"&gt;猛击这里&lt;/a&gt;。 &lt;p&gt;作为初入职场，特别是对于刚踏入社会的热血青年，其实很希望，即使是得到那么一丁点的指引，也足以让他们少奋斗一段历程。作为过来人，我为那些工作一两年仍然停留学生阶段的朋友感到惋惜，与其勉强为了专业对口而从事自己不擅长的工作，倒不如索性转行来得痛快。 &lt;p&gt;下面总结面试者和面试官两者应该具备的基本要求—— &lt;p&gt;&lt;p&gt;&lt;strong&gt;面试者应该了解&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;1. 笔试题做得好，不代表什么；但做不好，往往给面试官第一印象就不太好。即使卷面不合格，也不用妄自菲薄，因为说不定做得比你差的大有人在。 &lt;p&gt;2. 自我介绍不要三言两语就结束，即使是刚毕业的大学生也不至于这样吧？ &lt;p&gt;3. 你不用长得帅气或迷人，但请保持应有的仪态和谈吐。 &lt;p&gt;4. 永远永远不要把你的简历折得皱巴巴，因为它是你的敲门砖。 &lt;p&gt;5. 尽量保持微笑，以及眼睛注视对方，特别是当面试官提问的时候。 &lt;p&gt;6. 专业基础知识一定要扎实，不要告诉面试官你因为工作的原因而忘记了，因为这些知识不应该是用来记的。 &lt;p&gt;7. 当面试官问你是否掌握某方面技术，不要明明没了解过也说自己掌握，否则被问了一个很基础问题就哑口无言。 &lt;p&gt;8. 最好不要被动回答问题，面试官其实很想听听你独到的想法。 &lt;p&gt;9. 最好准备两个以上问题，礼貌地向面试官提问。 &lt;p&gt;10. 最后，如果你面试失败，其实有可能你不适合这个公司而已。 &lt;p&gt;&lt;p&gt;&lt;strong&gt;作为面试官，希望在这里抛砖引玉&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;1. 永远记住：发掘面试者的潜能是你的职责。 &lt;p&gt;2. 私人问题不要问，唯一一个例外就是：问面试者为何离开上一家公司。 &lt;p&gt;3. 不要带有感情色彩去面试，如果那天实在无法调整自己的情绪，把这重任交给其他人。 &lt;p&gt;4. 对于不合格的面试者，绝对不要有半点吝惜。 &lt;p&gt;5. 在面试者眼里，面试官代表公司形象，不要表现强势不可一世，否则毁了公司形象。 &lt;p&gt;6. 不要招聘心术不正之人，甭管他技术胜人一筹。 &lt;p&gt;7. 了解面试者自我学习和解决问题的能力。 &lt;p&gt;8. 不要光凭笔试题目为面试者打分。 &lt;p&gt;9. 真正有才华的人凤毛麟角，因此给自己更为面试者开一条路：你要招的只是合格者而已，将他与公司同等职位的人作比较是最合适不过。 &lt;p&gt;10. 最好一点，也是最重要一点：不要以为只有面试者在面试前要准备，面试官也不例外。 &lt;p&gt;&lt;p&gt;每年招聘或应聘的高峰期又如期而至了，祝找工作的如愿以偿，招聘的招到千里马或潜力股。 &lt;img src="http://www.cnblogs.com/coolcode/aggbug/1985459.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/coolcode/archive/2011/03/15/recruit_and_employ.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/coolcode/archive/2010/11/07/Agile.html</id><title type="text">敏捷全球之旅 - 广州</title><summary type="text">今天广州天气阳光明媚，我很高兴能参加“敏捷全球之旅”的讲座，亲临Scrum大师Vernon Stinebaker（中文名：史文林）的精彩演讲。趁着身上尚有敏捷的“余温”，记录一下今天的体会。</summary><published>2010-11-07T15:11:00Z</published><updated>2010-11-07T15:11:00Z</updated><author><name>CoolCode</name><uri>http://www.cnblogs.com/coolcode/</uri></author><link rel="alternate" href="http://www.cnblogs.com/coolcode/archive/2010/11/07/Agile.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/coolcode/archive/2010/11/07/Agile.html"/><content type="html">&lt;p&gt;今天广州天气阳光明媚，我很高兴能参加“敏捷全球之旅”的讲座，亲临Scrum大师Vernon Stinebaker（中文名：史文林）的精彩演讲。趁着身上尚有敏捷的“余温”，记录一下今天的体会。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;strong&gt;Vernon Stinebaker 的背景&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;博克软件杭州的技术与架构总监。他是目前国内仅有的两位Scrum联盟的认证Scrum培训师（CST）之一，具有资格通过培训颁发CSM及CSPO认证。&lt;/p&gt; &lt;p&gt;Vernon 能讲一口流利的普通话，但他在中国已经待了很长时间，学会了中国人的谦虚文化，只说自己“会讲一点普通话”。这次讲座为了不让外国嘉宾打瞌睡，他全程中英双语作演讲，将自己对Scrum的看法以及自身运用Scrum的经历分享给大家。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Scrum&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;他强调的Scrum的几个特点&lt;/p&gt; &lt;p&gt;1. 持续集成&lt;/p&gt; &lt;p&gt;2. 每日例会一定要站起来开&lt;/p&gt; &lt;p&gt;3. Sprint Review&lt;/p&gt; &lt;p&gt;4. 强调人&lt;/p&gt; &lt;p&gt;&lt;strong&gt;其他讲师&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;后续几位讲师的演讲的主题也不错。如李华北的“CMMI中的敏捷方法”介绍CMMI和敏捷的异同，以及两者可以并存改善软件过程；陈庆春的“敏捷需求面面观”提到软件的45%功能最终客户是不会用到的；谭小鹏的“需求-想得到你的心很难”提出需求并不是简单的事情，同时也结合自己的经验介绍如何取得用户的&lt;strong&gt;有效&lt;/strong&gt;需求……&lt;/p&gt; &lt;p&gt;&lt;strong&gt;疑问&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;会后和几位同事交流了这次讲座的体会，普遍产生一些疑问：&lt;/p&gt; &lt;p&gt;1. 敏捷是否适合自身公司？ &lt;/p&gt; &lt;p&gt;2. 敏捷是否会带来高项目成本？ &lt;/p&gt; &lt;p&gt;3. 敏捷的纪律性问题会带来风险吗？&lt;/p&gt; &lt;p&gt;4. TDD适合哪些类型项目？&lt;/p&gt; &lt;p&gt;据我所知，有两家中小型公司已经在用Scrum（尚处于Scrum的入门阶段），目前情况比较乐观，至少没有产生以上的问题。TDD基本上还没见到谁在用。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;随便说说&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;反观自己，已经3个月没更新博客了。一方面，是我关注的知识越来越多；另一方面，确实我的工作越来越忙。希望日后能挤出那么一点时间，多抛几块砖上来。&lt;/p&gt; &lt;p&gt;顺便推荐《Scrum敏捷项目管理》是本不错的书！&lt;/p&gt;&lt;img src="http://www.cnblogs.com/coolcode/aggbug/1871360.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/coolcode/archive/2010/11/07/Agile.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/coolcode/archive/2010/07/26/jstree_add_event_for_node_dblclick.html</id><title type="text">jquery.jstree 增加节点的双击事件</title><summary type="text">本文基于  jsTree 1.0-rc1 版本增加节点的双击事件。jsTree 是基于jquery的树插件，支持拖放、复制、删除、快捷键、多选、自定义节点图标、自定义右键菜单、跨页面保存状态等等，总之我想到的它基本上都有了，而且最值得表扬的是它让人感觉一点都不慢哦。</summary><published>2010-07-26T11:59:00Z</published><updated>2010-07-26T11:59:00Z</updated><author><name>CoolCode</name><uri>http://www.cnblogs.com/coolcode/</uri></author><link rel="alternate" href="http://www.cnblogs.com/coolcode/archive/2010/07/26/jstree_add_event_for_node_dblclick.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/coolcode/archive/2010/07/26/jstree_add_event_for_node_dblclick.html"/><content type="html">&lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;jstree&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;本文基于&amp;nbsp; &lt;a href="http://jstree.com/" target="_blank"&gt;jsTree&lt;/a&gt; 1.0-rc1 版本增加节点的双击事件。&lt;/p&gt; &lt;p&gt;&lt;a href="http://jstree.com/" target="_blank"&gt;jsTree&lt;/a&gt; 是基于jquery的树插件，支持拖放、复制、删除、快捷键、多选、自定义节点图标、自定义右键菜单、跨页面保存状态等等，总之我想到的它基本上都有了，而且最值得表扬的是它让人感觉一点都不慢哦。&lt;/p&gt; &lt;p&gt;jsTree有节点选择事件，即&lt;/p&gt;&lt;pre &gt;.bind(&lt;span style="color: #a31515"&gt;"select_node.jstree"&lt;/span&gt;, &lt;span style="color: blue"&gt;function&lt;/span&gt;(e, data) {&#xD;
             &lt;span style="color: green"&gt;//alert(data.rslt.obj.attr("id") + ":" + data.rslt.obj.attr("rel"));&#xD;
        &lt;/span&gt;})&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;其实我认为它更像是节点的&lt;strong&gt;单击&lt;/strong&gt;事件，因为每次点节点的时候它都会触发，不管之前该节点是否已经被选中。&lt;/p&gt;&#xD;
&lt;p&gt;近日做个文件管理的东东，需要用到节点的双击事件，如双击某个节点打开该节点的编辑页面。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/coolcode/WindowsLiveWriter/jquery.jstree_10B97/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/coolcode/WindowsLiveWriter/jquery.jstree_10B97/image_thumb.png" width="228" height="221"&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;jstree虽然有双击事件，但是并非针对节点的，而是你双击树所在区域就会触发，如上图任何一个地方。&lt;/p&gt;&#xD;
&lt;p&gt;离&lt;strong&gt;节点双击事件&lt;/strong&gt;最接近的应该就是&lt;strong&gt;节点选择事件&lt;/strong&gt;，因此又是“照葫芦画瓢”啦。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;分析&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在第833行 this.get_container() 后是节点的单击事件&lt;/p&gt;&lt;pre &gt;.delegate(&lt;span style="color: #a31515"&gt;"a"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"click.jstree"&lt;/span&gt;, $.proxy(&lt;span style="color: blue"&gt;function &lt;/span&gt;(event) {&#xD;
                        event.preventDefault();&#xD;
                        &lt;span style="color: blue"&gt;this&lt;/span&gt;.select_node(event.currentTarget, &lt;span style="color: blue"&gt;true&lt;/span&gt;, event);&#xD;
                    }, &lt;span style="color: blue"&gt;this&lt;/span&gt;))&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;同样我再这里插入节点双击事件&lt;/p&gt;&lt;pre &gt;.delegate(&lt;span style="color: #a31515"&gt;"a"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"dblclick.jstree"&lt;/span&gt;, $.proxy(&lt;span style="color: blue"&gt;function&lt;/span&gt;(event) {&#xD;
    event.preventDefault();&#xD;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.dblclick_node(event.currentTarget, &lt;span style="color: blue"&gt;true&lt;/span&gt;, event);&#xD;
    }, &lt;span style="color: blue"&gt;this&lt;/span&gt;))&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;接着，我再实现 &lt;strong&gt;dblclick_node&lt;/strong&gt; 方法就可以了。&lt;/p&gt;&#xD;
&lt;p&gt;在第928行找到 select_node 的代码，比较复杂。但里面90%对于双击来说是没有用处的，如处理单选、多选、保存选择结果到cookies等。因此 &lt;strong&gt;dblclick_node&lt;/strong&gt; 方法的实现要比 select_node 简单很多。&lt;/p&gt;&lt;pre &gt;dblclick_node: &lt;span style="color: blue"&gt;function&lt;/span&gt;(obj, check, e) {&#xD;
    obj = &lt;span style="color: blue"&gt;this&lt;/span&gt;._get_node(obj);&#xD;
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(obj == -1 || !obj || !obj.length) { &lt;span style="color: blue"&gt;return false&lt;/span&gt;; } &#xD;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.__callback({ &lt;span style="color: #a31515"&gt;"obj"&lt;/span&gt;: obj }); &#xD;
},&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;OK，就这样了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;使用例子&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;跟 select_node 用法一样&lt;/p&gt;&lt;pre &gt;.bind(&lt;span style="color: #a31515"&gt;"dblclick_node.jstree"&lt;/span&gt;, &lt;span style="color: blue"&gt;function&lt;/span&gt;(e, data) {&#xD;
             &lt;span style="color: green"&gt;//alert(data.rslt.obj.attr("id") + ":" + data.rslt.obj.attr("rel"));&#xD;
        &lt;/span&gt;})&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;改造后的代码下载&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://files.cnblogs.com/coolcode/jquery.jstree.js"&gt;jquery.jstree.js&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;顺便说说&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;jstree 跟另一个插件jquery &lt;strong&gt;validate &lt;/strong&gt;是水火不容的，当两者共存时，jstree虽然也可以构造树出来，但如僵尸一般不能展开。这里mark一个，日后试试能否修改。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/coolcode/aggbug/1785514.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/coolcode/archive/2010/07/26/jstree_add_event_for_node_dblclick.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/coolcode/archive/2010/07/18/when_ADO_NET_meets_dynamic.html</id><title type="text">当 ADO.NET 遇上 dynamic</title><summary type="text">某年某月ADO.NET不幸遇到dynamic，从此循规蹈矩的生活不复存在。dynamic说它可以帮助 ADO.NET 丢掉 DataSet 的包袱，而且在不用创建数据实体的情况下，实现查询结果垮不同方法传递；更加强大的地方是可以与存储过程无缝连接，即像调用一般方法一样调用存储过程而不用写额外代码。我的神哪～～～ </summary><published>2010-07-18T09:46:00Z</published><updated>2010-07-18T09:46:00Z</updated><author><name>CoolCode</name><uri>http://www.cnblogs.com/coolcode/</uri></author><link rel="alternate" href="http://www.cnblogs.com/coolcode/archive/2010/07/18/when_ADO_NET_meets_dynamic.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/coolcode/archive/2010/07/18/when_ADO_NET_meets_dynamic.html"/><content type="html">&lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;传说中的dynamic&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;dynamic是个不合群、不按规则办事的家伙，可以说是个异形，但更恐怖的是它又是无所不知的，任何事情都难不了它（咳咳，它似乎与Lambda表达式是死对头）。这令人想起《&lt;a href="http://baike.baidu.com/view/255867.htm" target="_blank"&gt;死亡日记&lt;/a&gt;》的怪异侦探L，行为怪异而智力超人，以至于离奇的案件不得不交给了他。dynamic可以看成是一切类型的化身，但并不是仅限于此，它像《&lt;a href="http://baike.baidu.com/view/1394304.htm" target="_blank"&gt;未来战士&lt;/a&gt;》续集里面的T-1000型液体金属的终结者。噢~~~~似乎扯的有点远了&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/coolcode/WindowsLiveWriter/dynamicADO.NET_1442C/9MV9FQGYXA1AJVJR%7BA%25RV%7DB_2.gif"&gt;&lt;img style="display: inline" title="9MV9FQGYXA1AJVJR{A%RV}B" alt="9MV9FQGYXA1AJVJR{A%RV}B" src="http://images.cnblogs.com/cnblogs_com/coolcode/WindowsLiveWriter/dynamicADO.NET_1442C/9MV9FQGYXA1AJVJR%7BA%25RV%7DB_thumb.gif" width="50" height="51"&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;饱经风雨而不倒的ADO.NET&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ADO.NET 从来做事都有理有据，而且又异常专注于自身领域，是个professional的牛人，令人想起《&lt;a href="http://baike.baidu.com/view/129715.htm" target="_blank"&gt;美丽心灵&lt;/a&gt;》里面的博弈论和微分几何学领域潜心研究以致获得诺贝尔经济学奖的数学家—— &lt;a href="http://baike.baidu.com/view/1197418.htm"&gt;约翰·福布斯·纳什&lt;/a&gt; 教授（咳咳，纳什教授是个妄想型精神分裂的～～～嗯，这个以后再说）。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;关于ADO.NET 的例子&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;1. 执行SQL语句&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DbCommand &lt;/span&gt;command = connection.CreateCommand())&#xD;
{&#xD;
    command.CommandText = &lt;span style="color: #a31515"&gt;"select Top 10 * from Orders"&lt;/span&gt;;&#xD;
    command.CommandType = &lt;span style="color: #2b91af"&gt;CommandType&lt;/span&gt;.Text;&#xD;
     &#xD;
    &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;IDataReader &lt;/span&gt;reader = command.ExecuteReader())&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;while &lt;/span&gt;(reader.Read())&#xD;
        {&#xD;
            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;"OrderID: {0}, OrderDate: {1}"&lt;/span&gt;,&#xD;
                reader.GetInt32(reader.GetOrdinal(&lt;span style="color: #a31515"&gt;"OrderID"&lt;/span&gt;)),&#xD;
                reader.GetDateTime(reader.GetOrdinal(&lt;span style="color: #a31515"&gt;"OrderDate"&lt;/span&gt;)));&#xD;
        }&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;2. 调用存储过程&lt;/p&gt;&lt;pre &gt;command.CommandText = &lt;span style="color: #a31515"&gt;"CustOrdersOrders"&lt;/span&gt;;&#xD;
         command.CommandType = &lt;span style="color: #2b91af"&gt;CommandType&lt;/span&gt;.StoredProcedure;&#xD;
         command.Parameters.Add(&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SqlParameter&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"CustomerID"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"ALFKI"&lt;/span&gt;));&#xD;
         &lt;span style="color: green"&gt;//略去...&#xD;
&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;当 ADO.NET 遇上 dynamic&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;某年某月ADO.NET不幸遇到dynamic，从此循规蹈矩的生活不复存在。dynamic说它可以帮助 ADO.NET 丢掉 DataSet 的包袱，而且在不用创建数据实体的情况下，实现查询结果垮不同方法传递；更加强大的地方是可以与存储过程无缝连接，即像调用一般方法一样调用存储过程而不用写额外代码。我的神哪～～～ ADO.NET 听了dynamic一番游说后，心底下不禁惊讶一下。dynamic又说，实现刚才所说的工程只要借你手下的两大猛将 SqlConnection 和 SqlCommand 助我一臂之力即可。&lt;/p&gt;&#xD;
&lt;p&gt;dynamic真有如此奇技？ ADO.NET 虽有怀疑，但它想到曾经看过一部叫《&lt;a href="http://baike.baidu.com/view/5829.htm" target="_blank"&gt;阿甘正传&lt;/a&gt;》的电影，里面的阿甘虽然是弱智人，但参军时练就乒乓奇技，后来还和中国国手同台竞技。想到这，ADO.NET 认为不能因为对方弱智就不相信对方的话，这是很不礼貌很不绅士的人才会做的事，所以它相信了dynamic。&lt;/p&gt;&#xD;
&lt;p&gt;dynamic 果真不负众望，三两脚猫功夫就交出成果了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;dynamic重构后的数据库操作&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;dynamic &lt;/span&gt;command = connection.CreateDynamicCommand())&#xD;
{&#xD;
    &lt;span style="color: green"&gt;//执行查询SQL&#xD;
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt;&amp;gt; toptenOrders = command(&lt;span style="color: #a31515"&gt;"select Top 10 * from Orders"&lt;/span&gt;);&#xD;
    &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;dynamic &lt;/span&gt;order &lt;span style="color: blue"&gt;in &lt;/span&gt;toptenOrders)&#xD;
    {&#xD;
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;"OrderID: {0}, OrderDate: {1}"&lt;/span&gt;, order.OrderID, order.OrderDate);&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: green"&gt;//执行带参数的SQL&#xD;
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt;&amp;gt; customerOrders = command(&lt;span style="color: #a31515"&gt;"select * from Orders where CustomerID = @CustomerID"&lt;/span&gt;,&#xD;
            CustomerID: &lt;span style="color: #a31515"&gt;"ALFKI"&lt;/span&gt;);&#xD;
    &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;dynamic &lt;/span&gt;order &lt;span style="color: blue"&gt;in &lt;/span&gt;customerOrders)&#xD;
    {&#xD;
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;"OrderID: {0}, OrderDate: {1}"&lt;/span&gt;, order.OrderID, order.OrderDate);&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: green"&gt;//调用存储过程&#xD;
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt;&amp;gt; orders = command.CustOrdersOrders(CustomerID: &lt;span style="color: #a31515"&gt;"ALFKI"&lt;/span&gt;);&#xD;
    &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;dynamic &lt;/span&gt;order &lt;span style="color: blue"&gt;in &lt;/span&gt;orders)&#xD;
    {&#xD;
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;"OrderID: {0}, OrderDate: {1}"&lt;/span&gt;, order.OrderID, order.OrderDate);&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;要知道 ADO.NET 可不是.NET菜鸟，它看到 command(&lt;span style="color: #a31515"&gt;"select Top 10 * from Orders"&lt;/span&gt;); 第一感觉认为吃了dynamic药的command有可能是委托类型，而看到后面的 command.CustOrdersOrders(CustomerID: &lt;span style="color: #a31515"&gt;"ALFKI"&lt;/span&gt;); 不得不否决了前面的看法。dynamic到底是什么东西？可以这样认为，dynamic什么东西都是；也可以认为，dynamic不是什么东西！&lt;/p&gt;&#xD;
&lt;p&gt;ADO.NET 知道任何.NET写的再高深的代码在reflector下都会现出原形，通过对 command 解剖，立刻明白原来自己跟《&lt;a href="http://baike.baidu.com/view/129715.htm" target="_blank"&gt;美丽心灵&lt;/a&gt;》的纳什教授一样纠缠于一种不存在的幻想不能自拔，reflector告诉我们：dynamic实际上是不存在的！&lt;/p&gt;&#xD;
&lt;p&gt;还是鲁迅叔叔说的好，&lt;strong&gt;&lt;font color="#ff8000"&gt;世界上本没有dynamic，只是微软对委托封装得太牛了，也便有了dynamic。&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;结语&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;聪明的你知道command是怎么实现了吗？不妨先想想，然后展开下面的代码看看是否与你想的一致。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="#" onclick="$('#divHideCode').toggle();return false;"&gt;点此展开代码&lt;/a&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;注：本文存储过程部分参考了&lt;a href="http://www.infoq.com/cn/articles/MicroORM" target="_blank"&gt;微型ORM&lt;/a&gt;.&lt;/p&gt;&#xD;
&#xD;
&lt;div id="divHideCode" style="display:none;"&gt;&#xD;
&lt;pre &gt;&lt;span style="color: blue"&gt;public static class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Extensions&#xD;
&lt;/span&gt;{&#xD;
    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DynamicCommand &lt;/span&gt;CreateDynamicCommand(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DbConnection &lt;/span&gt;connection)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DynamicCommand&lt;/span&gt;(connection);&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;pre &gt;&lt;span style="color: gray"&gt;    /// &amp;lt;summary&amp;gt;&#xD;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;动态Command&#xD;
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;&#xD;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DynamicCommand &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;DynamicObject&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;IDisposable&#xD;
    &lt;/span&gt;{&#xD;
        &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DbConnection &lt;/span&gt;Connection { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&#xD;
&#xD;
        &lt;span style="color: blue"&gt;public &lt;/span&gt;DynamicCommand(&lt;span style="color: #2b91af"&gt;DbConnection &lt;/span&gt;connection)&#xD;
        {&#xD;
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.Connection = connection;&#xD;
        }&#xD;
&#xD;
        &lt;span style="color: green"&gt;//实现SQL语句查询&#xD;
        &lt;/span&gt;&lt;span style="color: blue"&gt;public override bool &lt;/span&gt;TryInvoke(&lt;span style="color: #2b91af"&gt;InvokeBinder &lt;/span&gt;binder, &lt;span style="color: blue"&gt;object&lt;/span&gt;[] args, &lt;span style="color: blue"&gt;out object &lt;/span&gt;result)&#xD;
        {&#xD;
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(args.Length == 0) &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"args must has value"&lt;/span&gt;);&#xD;
&#xD;
            result = Execute(args[0].ToString(), &lt;span style="color: #2b91af"&gt;CommandType&lt;/span&gt;.Text, binder.CallInfo.ArgumentNames, args.Skip(1).ToArray());&#xD;
&#xD;
            &lt;span style="color: blue"&gt;return true&lt;/span&gt;;&#xD;
        }&#xD;
&#xD;
        &lt;span style="color: green"&gt;//实现存储过程&#xD;
        &lt;/span&gt;&lt;span style="color: blue"&gt;public override bool &lt;/span&gt;TryInvokeMember(&lt;span style="color: #2b91af"&gt;InvokeMemberBinder &lt;/span&gt;binder, &lt;span style="color: blue"&gt;object&lt;/span&gt;[] args, &lt;span style="color: blue"&gt;out object &lt;/span&gt;result)&#xD;
        {&#xD;
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(binder.CallInfo.ArgumentNames.Count != binder.CallInfo.ArgumentCount)&#xD;
            {&#xD;
                &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"All parameters must be named"&lt;/span&gt;);&#xD;
            }&#xD;
            &#xD;
            result = Execute(binder.Name, &lt;span style="color: #2b91af"&gt;CommandType&lt;/span&gt;.StoredProcedure, binder.CallInfo.ArgumentNames, args);&#xD;
&#xD;
            &lt;span style="color: blue"&gt;return true&lt;/span&gt;;&#xD;
        }&#xD;
&#xD;
        &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;&#xD;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;执行SQL查询&#xD;
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;&#xD;
        /// &amp;lt;param name="commandText"&amp;gt;&amp;lt;/param&amp;gt;&#xD;
        /// &amp;lt;param name="commandType"&amp;gt;&amp;lt;/param&amp;gt;&#xD;
        /// &amp;lt;param name="names"&amp;gt;&amp;lt;/param&amp;gt;&#xD;
        /// &amp;lt;param name="args"&amp;gt;&amp;lt;/param&amp;gt;&#xD;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&#xD;
        &lt;/span&gt;&lt;span style="color: blue"&gt;private object &lt;/span&gt;Execute(&lt;span style="color: blue"&gt;string &lt;/span&gt;commandText, &lt;span style="color: #2b91af"&gt;CommandType &lt;/span&gt;commandType, &lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; names, &lt;span style="color: blue"&gt;object&lt;/span&gt;[] args)&#xD;
        {&#xD;
            &lt;span style="color: blue"&gt;bool &lt;/span&gt;manageConnectionLifespan = (&lt;span style="color: blue"&gt;this&lt;/span&gt;.Connection.State == &lt;span style="color: #2b91af"&gt;ConnectionState&lt;/span&gt;.Closed);&#xD;
&#xD;
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(manageConnectionLifespan) &lt;span style="color: blue"&gt;this&lt;/span&gt;.Connection.Open();&#xD;
&#xD;
            &lt;span style="color: blue"&gt;try&#xD;
            &lt;/span&gt;{&#xD;
                &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;cmd = &lt;span style="color: blue"&gt;this&lt;/span&gt;.Connection.CreateCommand())&#xD;
                {&#xD;
                    cmd.CommandType = commandType;&#xD;
                    cmd.CommandText = commandText;&#xD;
                    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; args.Length; i++)&#xD;
                    {&#xD;
                        &lt;span style="color: #2b91af"&gt;DbParameter &lt;/span&gt;param = cmd.CreateParameter();&#xD;
                        param.ParameterName = &lt;span style="color: #a31515"&gt;"@" &lt;/span&gt;+ names.ElementAt(i);&#xD;
                        param.Value = args[i] == &lt;span style="color: blue"&gt;null &lt;/span&gt;? &lt;span style="color: #2b91af"&gt;DBNull&lt;/span&gt;.Value : args[i];&#xD;
                        cmd.Parameters.Add(param);&#xD;
                    }&#xD;
&#xD;
                    &lt;span style="color: blue"&gt;return &lt;/span&gt;ExecuteList(cmd);&#xD;
                }&#xD;
            }&#xD;
            &lt;span style="color: blue"&gt;finally&#xD;
            &lt;/span&gt;{&#xD;
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(manageConnectionLifespan)&#xD;
                {&#xD;
                    &lt;span style="color: blue"&gt;this&lt;/span&gt;.Connection.Close();&#xD;
                }&#xD;
            }&#xD;
        }&#xD;
&#xD;
        &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;&#xD;
        /// &lt;/span&gt;&lt;span style="color: green"&gt;执行SQL命令，返回查询结果列表&#xD;
        &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;&#xD;
        /// &amp;lt;param name="command"&amp;gt;&amp;lt;/param&amp;gt;&#xD;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&#xD;
        &lt;/span&gt;&lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt;&amp;gt; ExecuteList(&lt;span style="color: #2b91af"&gt;DbCommand &lt;/span&gt;command)&#xD;
        {&#xD;
            &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicEntity&lt;/span&gt;&amp;gt; resultList = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DynamicEntity&lt;/span&gt;&amp;gt;();&#xD;
            &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DbDataReader &lt;/span&gt;reader = command.ExecuteReader())&#xD;
            {&#xD;
                &lt;span style="color: blue"&gt;while &lt;/span&gt;(reader.Read())&#xD;
                {&#xD;
                    &lt;span style="color: #2b91af"&gt;DynamicEntity &lt;/span&gt;entity = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DynamicEntity&lt;/span&gt;();&#xD;
                    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; reader.FieldCount; i++)&#xD;
                    {&#xD;
                        entity.SetMember(reader.GetName(i), reader.GetValue(i));&#xD;
                    }&#xD;
                    resultList.Add(entity);&#xD;
                }&#xD;
            }&#xD;
            &lt;span style="color: blue"&gt;return &lt;/span&gt;resultList;&#xD;
        }&#xD;
&#xD;
    }&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;pre &gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;&#xD;
/// &lt;/span&gt;&lt;span style="color: green"&gt;动态实体&#xD;
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;&#xD;
&lt;/span&gt;&lt;span style="color: blue"&gt;internal class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DynamicEntity &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;DynamicObject&#xD;
&lt;/span&gt;{&#xD;
    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;&#xD;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;属性和值的字典表&#xD;
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;&#xD;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt; values = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;(&lt;span style="color: #2b91af"&gt;StringComparer&lt;/span&gt;.OrdinalIgnoreCase);&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public override bool &lt;/span&gt;TryGetMember(&lt;span style="color: #2b91af"&gt;GetMemberBinder &lt;/span&gt;binder, &lt;span style="color: blue"&gt;out object &lt;/span&gt;result)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(values.ContainsKey(binder.Name))&#xD;
        {&#xD;
            result = values[binder.Name];&#xD;
        }&#xD;
        &lt;span style="color: blue"&gt;else&#xD;
        &lt;/span&gt;{&#xD;
            &lt;span style="color: blue"&gt;throw new &lt;/span&gt;System.&lt;span style="color: #2b91af"&gt;MissingMemberException&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"The property " &lt;/span&gt;+ binder.Name + &lt;span style="color: #a31515"&gt;" does not exist"&lt;/span&gt;);&#xD;
        }&#xD;
&#xD;
        &lt;span style="color: blue"&gt;return true&lt;/span&gt;;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public override bool &lt;/span&gt;TrySetMember(&lt;span style="color: #2b91af"&gt;SetMemberBinder &lt;/span&gt;binder, &lt;span style="color: blue"&gt;object &lt;/span&gt;value)&#xD;
    {&#xD;
        SetMember(binder.Name, value);&#xD;
        &lt;span style="color: blue"&gt;return true&lt;/span&gt;;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;public override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; GetDynamicMemberNames()&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;values.Keys;&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;internal void &lt;/span&gt;SetMember(&lt;span style="color: blue"&gt;string &lt;/span&gt;propertyName, &lt;span style="color: blue"&gt;object &lt;/span&gt;value)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;object&lt;/span&gt;.ReferenceEquals(value, &lt;span style="color: #2b91af"&gt;DBNull&lt;/span&gt;.Value))&#xD;
        {&#xD;
            values[propertyName] = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&#xD;
        }&#xD;
        &lt;span style="color: blue"&gt;else&#xD;
        &lt;/span&gt;{&#xD;
            values[propertyName] = value;&#xD;
        }&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;img src="http://www.cnblogs.com/coolcode/aggbug/1780241.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/coolcode/archive/2010/07/18/when_ADO_NET_meets_dynamic.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/coolcode/archive/2010/07/11/LinqToSQL_Batch_Update.html</id><title type="text">Linq To SQL 批量更新方法汇总</title><summary type="text">本文详细介绍了四种 Linq To SQL 批量更新的方法。方法一、官方例子方法二、使用ExpressionVisitor获取Lambda表达式生成的SQL条件语句方法三、使用 LinqToSQL 自身的解析器来获取Lambda表达式生成的SQL条件语句方法四、支持多表关联的复杂条件</summary><published>2010-07-11T12:49:00Z</published><updated>2010-07-11T12:49:00Z</updated><author><name>CoolCode</name><uri>http://www.cnblogs.com/coolcode/</uri></author><link rel="alternate" href="http://www.cnblogs.com/coolcode/archive/2010/07/11/LinqToSQL_Batch_Update.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/coolcode/archive/2010/07/11/LinqToSQL_Batch_Update.html"/><content type="html">&lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;方法一、官方例子&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;地球人都知道的，也是不少 Linq To SQL 反对者认为效率低下的一种方法。&lt;/p&gt;&lt;pre &gt;&lt;span style="color: #2b91af"&gt;NorthwindDataContext &lt;/span&gt;db = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NorthwindDataContext&lt;/span&gt;();&#xD;
&lt;span style="color: blue"&gt;var &lt;/span&gt;customers = db.Customers.Where(c =&amp;gt; c.CustomerID.StartsWith(&lt;span style="color: #a31515"&gt;"BL"&lt;/span&gt;));&#xD;
&lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;customer &lt;span style="color: blue"&gt;in &lt;/span&gt;customers)&#xD;
{&#xD;
    customer.Address = &lt;span style="color: #a31515"&gt;"Guangzhou"&lt;/span&gt;;&#xD;
    customer.ContactName = &lt;span style="color: #a31515"&gt;"CoolCode"&lt;/span&gt;;&#xD;
    customer.CompanyName = &lt;span style="color: #a31515"&gt;"Microsoft"&lt;/span&gt;;&#xD;
}&#xD;
db.SubmitChanges();&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这种方法必须要查询出要更新的数据，确实有点不雅，也是Linq To SQL 略显尴尬的一面。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;方法二、使用&lt;strong&gt;ExpressionVisitor&lt;/strong&gt;获取Lambda表达式生成的SQL条件语句&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;此方法是基于Jeffrey Zhao 的《&lt;a href="http://www.cnblogs.com/JeffreyZhao/archive/2008/03/05/linq-to-sql-batch-delete-extension.html"&gt;扩展LINQ to SQL：使用Lambda Expression批量删除数据&lt;/a&gt;》，从该文章得到一点启发，继而有了批量更新。使用示例：&lt;/p&gt;&lt;pre &gt;db.Customers.Update(c =&amp;gt; c.CustomerID == &lt;span style="color: #a31515"&gt;"Bruce"&lt;/span&gt;,&#xD;
                     c =&amp;gt; &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Customer&#xD;
                     &lt;/span&gt;{&#xD;
                         Address = &lt;span style="color: #a31515"&gt;"Guangzhou"&lt;/span&gt;,&#xD;
                         ContactName = &lt;span style="color: #a31515"&gt;"CoolCode"&lt;/span&gt;,&#xD;
                         CompanyName = &lt;span style="color: #a31515"&gt;"Microsoft"&#xD;
                     &lt;/span&gt;});&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;方法原型&lt;/strong&gt;：&lt;/p&gt;&lt;pre &gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;&#xD;
/// &lt;/span&gt;&lt;span style="color: green"&gt;批量更新&#xD;
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;&#xD;
/// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&#xD;
/// &amp;lt;param name="table"&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;表&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&#xD;
/// &amp;lt;param name="predicate"&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;查询条件表达式&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&#xD;
/// &amp;lt;param name="updater"&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;更新表达式&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&#xD;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;影响的行数&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/returns&amp;gt;&#xD;
&lt;/span&gt;&lt;span style="color: blue"&gt;public static int &lt;/span&gt;Update&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Table&lt;/span&gt;&amp;lt;T&amp;gt; table, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; predicate, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T,T&amp;gt;&amp;gt; updater) &lt;span style="color: blue"&gt;where &lt;/span&gt;T : &lt;span style="color: blue"&gt;class&#xD;
&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;实现原理&lt;/strong&gt;：扩展Table&amp;lt;T&amp;gt;，解释表达式树成SQL语句。其中解释表达式树包括和更新表达式，后者相对容易处理，例如表达式：&lt;/p&gt;&#xD;
&lt;p&gt;c =&amp;gt; &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Customer &lt;/span&gt;{ Address = &lt;span style="color: #a31515"&gt;"Guangzhou"&lt;/span&gt;, ContactName = &lt;span style="color: #a31515"&gt;"CoolCode"&lt;/span&gt;, CompanyName = &lt;span style="color: #a31515"&gt;"Microsoft" &lt;/span&gt;}&lt;/p&gt;&#xD;
&lt;p&gt;解释成&lt;/p&gt;&#xD;
&lt;p&gt;Address = &lt;span style="color: #a31515"&gt;@Address&lt;/span&gt;, ContactName = &lt;span style="color: #a31515"&gt;@ContactName&lt;/span&gt;, CompanyName = &lt;span style="color: #a31515"&gt;@CompanyName&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;而相应的值（&lt;span style="color: #a31515"&gt;"Guangzhou", &lt;span style="color: #a31515"&gt;"CoolCode"&lt;/span&gt;,&amp;nbsp; &lt;span style="color: #a31515"&gt;"Microsoft" &lt;/span&gt;&lt;/span&gt;）作为SQL参数传递。&lt;/p&gt;&#xD;
&lt;p&gt;实现这一步，其实就是从表达式 &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T,T&amp;gt;&amp;gt; 中取到初始化的属性名字和值就可以，具体做法可以使用Expression Tree Viewer来辅助，从下图可以了解到 &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T,T&amp;gt;&amp;gt; 的树形结构。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/coolcode/WindowsLiveWriter/LinqToSQL_CB64/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/coolcode/WindowsLiveWriter/LinqToSQL_CB64/image_thumb_1.png" width="676" height="640"&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;然后我按上面的结构图“照葫芦画瓢”就得到要更新的属性名字和值：&lt;/p&gt;&lt;pre &gt;&lt;span style="color: green"&gt;//获取Update的赋值语句&#xD;
&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;updateMemberExpr = (&lt;span style="color: #2b91af"&gt;MemberInitExpression&lt;/span&gt;)updater.Body;&#xD;
&lt;span style="color: blue"&gt;var &lt;/span&gt;updateMemberCollection = updateMemberExpr.Bindings.Cast&amp;lt;&lt;span style="color: #2b91af"&gt;MemberAssignment&lt;/span&gt;&amp;gt;().Select(c =&amp;gt; &lt;span style="color: blue"&gt;new&#xD;
&lt;/span&gt;{&#xD;
    Name = c.Member.Name,&#xD;
    Value = ((&lt;span style="color: #2b91af"&gt;ConstantExpression&lt;/span&gt;)c.Expression).Value&#xD;
});&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;而解释where条件就相对没这么轻松了。&lt;/p&gt;&#xD;
&lt;p&gt;这里同 Jeffrey Zhao 的批量删除一样，同样是借助 ExpressionVisitor 来解释。ExpressionVisitor 是 &lt;a href="http://www.cnblogs.com/coolcode/archive/2010/05/26/Why_I_need_to_learn_Expression_Tree.html" target="_blank"&gt;Expression Tree&lt;/a&gt; 的遍历器，它自身不会帮你生成任何东西，通过继承 ExpressionVisitor 就可以取表达式的任何信息，本文就是通过让 ConditionBuilder 继承ExpressionVisitor 而生成 Where 条件的 SQL。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;注&lt;/strong&gt;：Jeffrey Zhao 的批量删除一文提供的源代码中，ConditionBuilder 并不支持生成Like操作，如 字符串的 StartsWith，Contains，EndsWith 并不能生成这样的SQL： Like ‘xxx%’, Like ‘%xxx%’ , Like ‘%xxx’ 。我通过分析 ExpressionVisitor ，也不难发现只要override VisitMethodCall 这个方法即可实现上述功能。&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;protected override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Expression &lt;/span&gt;VisitMethodCall(&lt;span style="color: #2b91af"&gt;MethodCallExpression &lt;/span&gt;m)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(m == &lt;span style="color: blue"&gt;null&lt;/span&gt;) &lt;span style="color: blue"&gt;return &lt;/span&gt;m;&#xD;
&#xD;
    &lt;span style="color: blue"&gt;string &lt;/span&gt;format;&#xD;
    &lt;span style="color: blue"&gt;switch &lt;/span&gt;(m.Method.Name)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;"StartsWith"&lt;/span&gt;:&#xD;
            format = &lt;span style="color: #a31515"&gt;"({0} LIKE {1}+'%')"&lt;/span&gt;;&#xD;
            &lt;span style="color: blue"&gt;break&lt;/span&gt;;&#xD;
&#xD;
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;"Contains"&lt;/span&gt;:&#xD;
            format = &lt;span style="color: #a31515"&gt;"({0} LIKE '%'+{1}+'%')"&lt;/span&gt;;&#xD;
            &lt;span style="color: blue"&gt;break&lt;/span&gt;;&#xD;
&#xD;
        &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;"EndsWith"&lt;/span&gt;:&#xD;
            format = &lt;span style="color: #a31515"&gt;"({0} LIKE '%'+{1})"&lt;/span&gt;;&#xD;
            &lt;span style="color: blue"&gt;break&lt;/span&gt;;&#xD;
&#xD;
        &lt;span style="color: blue"&gt;default&lt;/span&gt;:&#xD;
            &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NotSupportedException&lt;/span&gt;(m.NodeType + &lt;span style="color: #a31515"&gt;" is not supported!"&lt;/span&gt;);&#xD;
    }&#xD;
&#xD;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.Visit(m.Object);&#xD;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.Visit(m.Arguments[0]);&#xD;
    &lt;span style="color: blue"&gt;string &lt;/span&gt;right = &lt;span style="color: blue"&gt;this&lt;/span&gt;.m_conditionParts.Pop();&#xD;
    &lt;span style="color: blue"&gt;string &lt;/span&gt;left = &lt;span style="color: blue"&gt;this&lt;/span&gt;.m_conditionParts.Pop();&#xD;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.m_conditionParts.Push(&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format(format, left, right));&#xD;
&#xD;
    &lt;span style="color: blue"&gt;return &lt;/span&gt;m;&#xD;
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;到此刻，已经解决了解释表达式树的难题，那么实现通过表达式树生成完整的 Update SQL语句这个设想也不是什么难事了。&lt;/p&gt;&lt;pre &gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;&#xD;
/// &lt;/span&gt;&lt;span style="color: green"&gt;批量更新&#xD;
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;&#xD;
/// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&#xD;
/// &amp;lt;param name="table"&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;表&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&#xD;
/// &amp;lt;param name="predicate"&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;查询条件表达式&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&#xD;
/// &amp;lt;param name="updater"&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;更新表达式&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&#xD;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;影响的行数&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/returns&amp;gt;&#xD;
&lt;/span&gt;&lt;span style="color: blue"&gt;public static int &lt;/span&gt;Update&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Table&lt;/span&gt;&amp;lt;T&amp;gt; table, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; predicate, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T,T&amp;gt;&amp;gt; updater) &lt;span style="color: blue"&gt;where &lt;/span&gt;T : &lt;span style="color: blue"&gt;class&#xD;
&lt;/span&gt;{&#xD;
    &lt;span style="color: green"&gt;//获取表名&#xD;
    &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;tableName = table.Context.Mapping.GetTable(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(T)).TableName;&#xD;
&#xD;
    &lt;span style="color: green"&gt;//查询条件表达式转换成SQL的条件语句&#xD;
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ConditionBuilder &lt;/span&gt;builder = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ConditionBuilder&lt;/span&gt;();&#xD;
    builder.Build(predicate.Body);&#xD;
    &lt;span style="color: blue"&gt;string &lt;/span&gt;sqlCondition = builder.Condition;&#xD;
&#xD;
    &lt;span style="color: green"&gt;//获取Update的赋值语句&#xD;
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;updateMemberExpr = (&lt;span style="color: #2b91af"&gt;MemberInitExpression&lt;/span&gt;)updater.Body;&#xD;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;updateMemberCollection = updateMemberExpr.Bindings.Cast&amp;lt;&lt;span style="color: #2b91af"&gt;MemberAssignment&lt;/span&gt;&amp;gt;().Select(c =&amp;gt; &lt;span style="color: blue"&gt;new&#xD;
    &lt;/span&gt;{&#xD;
        Name = c.Member.Name,&#xD;
        Value = ((&lt;span style="color: #2b91af"&gt;ConstantExpression&lt;/span&gt;)c.Expression).Value&#xD;
    });&#xD;
&#xD;
    &lt;span style="color: blue"&gt;int &lt;/span&gt;i = builder.Arguments.Length;&#xD;
    &lt;span style="color: blue"&gt;string &lt;/span&gt;sqlUpdateBlock = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Join(&lt;span style="color: #a31515"&gt;", "&lt;/span&gt;, updateMemberCollection.Select(c =&amp;gt; &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"[{0}]={1}"&lt;/span&gt;, c.Name, &lt;span style="color: #a31515"&gt;"{" &lt;/span&gt;+ (i++) + &lt;span style="color: #a31515"&gt;"}"&lt;/span&gt;)).ToArray());&#xD;
&#xD;
    &lt;span style="color: green"&gt;//SQL命令&#xD;
    &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;commandText = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"UPDATE {0} SET {1} WHERE {2}"&lt;/span&gt;, tableName, sqlUpdateBlock, sqlCondition);&#xD;
&#xD;
    &lt;span style="color: green"&gt;//获取SQL参数数组 (包括查询参数和赋值参数)&#xD;
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;args = builder.Arguments.Union(updateMemberCollection.Select(c =&amp;gt; c.Value)).ToArray();&#xD;
&#xD;
    &lt;span style="color: green"&gt;//执行&#xD;
    &lt;/span&gt;&lt;span style="color: blue"&gt;return &lt;/span&gt;table.Context.ExecuteCommand(commandText, args);&#xD;
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;例如上面提到的示例所生成的 Updae SQL语句是：&lt;/p&gt;&#xD;
&lt;p&gt;UPDATE dbo.Customers SET [Address]={1}, [ContactName]={2}, [CompanyName]={3} WHERE ([CustomerID] = {0})&lt;/p&gt;&#xD;
&lt;p&gt;相应参数：&lt;span style="color: #a31515"&gt;"Bruce", &lt;/span&gt;&lt;span style="color: #a31515"&gt;"Guangzhou", &lt;span style="color: #a31515"&gt;"CoolCode"&lt;/span&gt;,&amp;nbsp; &lt;span style="color: #a31515"&gt;"Microsoft" &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;据不完全统计，实际开发中用的 Update SQL 90%是很简单的，以上扩展基本上符合要求。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;方法三、使用 &lt;strong&gt;LinqToSQL&lt;/strong&gt; 自身的解析器来获取Lambda表达式生成的SQL条件语句&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;该方法与方法二基本上是同一思路，只是在获取Lambda表达式生成的SQL条件上有点不一样。&lt;/p&gt;&#xD;
&lt;p&gt;通过 DataContext 的 GetCommand 可以获取到 DbCommand，所以通过生成的SQL查询语句中截取Where后面的条件，再用方法二生成Update 的赋值语句，两者拼凑起来即可。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/coolcode/WindowsLiveWriter/LinqToSQL_CB64/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/coolcode/WindowsLiveWriter/LinqToSQL_CB64/image_thumb_2.png" width="708" height="300"&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;该方法比方法二支持更多Lambda表达式（实际上就是所有LinqToSQL支持的）生成SQL条件。&lt;/p&gt;&lt;pre &gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;&#xD;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;批量更新&#xD;
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;&#xD;
    /// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&#xD;
    /// &amp;lt;param name="table"&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;表&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&#xD;
    /// &amp;lt;param name="predicate"&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;查询条件表达式&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&#xD;
    /// &amp;lt;param name="updater"&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;更新表达式&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&#xD;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;影响的行数&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/returns&amp;gt;&#xD;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static int &lt;/span&gt;Update&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Table&lt;/span&gt;&amp;lt;T&amp;gt; table, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; predicate, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T,T&amp;gt;&amp;gt; updater) &lt;span style="color: blue"&gt;where &lt;/span&gt;T : &lt;span style="color: blue"&gt;class&#xD;
    &lt;/span&gt;{&#xD;
        &lt;span style="color: green"&gt;//获取表名&#xD;
        &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;tableName = table.Context.Mapping.GetTable(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(T)).TableName;&#xD;
        &lt;span style="color: #2b91af"&gt;DbCommand &lt;/span&gt;command = table.Context.GetCommand(table.Where(predicate));&#xD;
        &lt;span style="color: blue"&gt;string &lt;/span&gt;sqlCondition = command.CommandText;&#xD;
        sqlCondition = sqlCondition.Substring(sqlCondition.LastIndexOf(&lt;span style="color: #a31515"&gt;"WHERE "&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;StringComparison&lt;/span&gt;.InvariantCultureIgnoreCase) + 6);&#xD;
&#xD;
        &lt;span style="color: green"&gt;//获取Update的赋值语句&#xD;
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;updateMemberExpr = (&lt;span style="color: #2b91af"&gt;MemberInitExpression&lt;/span&gt;)updater.Body;&#xD;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;updateMemberCollection = updateMemberExpr.Bindings.Cast&amp;lt;&lt;span style="color: #2b91af"&gt;MemberAssignment&lt;/span&gt;&amp;gt;().Select(c =&amp;gt;&#xD;
        {&#xD;
            &lt;span style="color: blue"&gt;var &lt;/span&gt;p = command.CreateParameter();&#xD;
            p.ParameterName = c.Member.Name;&#xD;
            p.Value = ((&lt;span style="color: #2b91af"&gt;ConstantExpression&lt;/span&gt;)c.Expression).Value;&#xD;
            &lt;span style="color: blue"&gt;return &lt;/span&gt;p;&#xD;
        })&#xD;
        .ToArray();&#xD;
&#xD;
        &lt;span style="color: blue"&gt;string &lt;/span&gt;sqlUpdateBlock = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Join(&lt;span style="color: #a31515"&gt;", "&lt;/span&gt;, updateMemberCollection.Select(c =&amp;gt; &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"[{0}]=@{0}"&lt;/span&gt;, c.ParameterName)).ToArray());&#xD;
&#xD;
        &lt;span style="color: green"&gt;//SQL命令&#xD;
        &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;commandText = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"UPDATE {0} SET {1} FROM {0} AS t0 WHERE {2}"&lt;/span&gt;, tableName, sqlUpdateBlock, sqlCondition);&#xD;
&#xD;
        &lt;span style="color: green"&gt;//获取SQL参数数组 (包括查询参数和赋值参数)&#xD;
        &lt;/span&gt;command.Parameters.AddRange(updateMemberCollection);&#xD;
        command.CommandText = commandText; &#xD;
&#xD;
        &lt;span style="color: green"&gt;//执行 &#xD;
        &lt;/span&gt;&lt;span style="color: blue"&gt;try&#xD;
        &lt;/span&gt;{&#xD;
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(command.Connection.State != &lt;span style="color: #2b91af"&gt;ConnectionState&lt;/span&gt;.Open)&#xD;
            {&#xD;
                command.Connection.Open();&#xD;
            }&#xD;
            &lt;span style="color: blue"&gt;return &lt;/span&gt;command.ExecuteNonQuery();&#xD;
        }&#xD;
        &lt;span style="color: blue"&gt;finally&#xD;
        &lt;/span&gt;{&#xD;
            command.Connection.Close();&#xD;
            command.Dispose();&#xD;
        }&#xD;
    }&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;同样使用文章开头的示例，生成的 Update SQL 跟方法二略有不同：&lt;/p&gt;&#xD;
&lt;p&gt;UPDATE dbo.Customers SET [Address]=@Address, [ContactName]=@ContactName, [CompanyName]=@CompanyName FROM dbo.Customers AS t0 WHERE [t0].[CustomerID] = @p0&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;方法四、支持多表关联的复杂条件&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;要知道，前面提到的方法二和三都不支持多表关联的复杂条件。可以用一个示例让大家更清楚为什么——&lt;/p&gt;&#xD;
&lt;p&gt;例如，更新CustomerID=“Bruce”的用户的所有订单的送货日前是一个月后。&lt;/p&gt;&lt;pre &gt;db.Orders.Update(c =&amp;gt; c.Customer.CustomerID == &lt;span style="color: #a31515"&gt;"Bruce"&lt;/span&gt;,&#xD;
                    c =&amp;gt; &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Order&#xD;
                    &lt;/span&gt;{&#xD;
                         ShippedDate =  &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now.AddMonths(1)&#xD;
                    });&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;应该生成的 Update SQL 语句是：&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;UPDATE &lt;/span&gt;[dbo]&lt;span style="color: gray"&gt;.&lt;/span&gt;[Orders] &lt;span style="color: blue"&gt;SET &lt;/span&gt;[ShippedDate] &lt;span style="color: gray"&gt;= &lt;/span&gt;@p1&#xD;
&lt;span style="color: blue"&gt;FROM &lt;/span&gt;[dbo]&lt;span style="color: gray"&gt;.&lt;/span&gt;[Orders] &lt;span style="color: blue"&gt;AS &lt;/span&gt;[t0]&#xD;
    &lt;span style="color: gray"&gt;LEFT OUTER JOIN &lt;/span&gt;[dbo]&lt;span style="color: gray"&gt;.&lt;/span&gt;[Customers] &lt;span style="color: blue"&gt;AS &lt;/span&gt;[t1] &lt;span style="color: blue"&gt;ON &lt;/span&gt;[t1]&lt;span style="color: gray"&gt;.&lt;/span&gt;[CustomerID] &lt;span style="color: gray"&gt;= &lt;/span&gt;[t0]&lt;span style="color: gray"&gt;.&lt;/span&gt;[CustomerID]&#xD;
&lt;span style="color: blue"&gt;WHERE &lt;/span&gt;[t1]&lt;span style="color: gray"&gt;.&lt;/span&gt;[CustomerID] &lt;span style="color: gray"&gt;= &lt;/span&gt;@p0&#xD;
&lt;span style="color: green"&gt;--@p0 = 'Bruce', @p1 = '2010-08-11'&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;但遗憾的是无论用方法二或三都会抛异常，因为两者皆没法解释多表关联生成的语句： “&lt;span style="color: gray"&gt;LEFT OUTER JOIN &lt;/span&gt;[dbo]&lt;span style="color: gray"&gt;.&lt;/span&gt;[Customers] &lt;span style="color: blue"&gt;AS &lt;/span&gt;[t1] &lt;span style="color: blue"&gt;ON &lt;/span&gt;[t1]&lt;span style="color: gray"&gt;.&lt;/span&gt;[CustomerID] &lt;span style="color: gray"&gt;= &lt;/span&gt;[t0]&lt;span style="color: gray"&gt;.&lt;/span&gt;[CustomerID] ”&lt;/p&gt;&#xD;
&lt;p&gt;一位叫 &lt;a href="http://www.aneyfamily.com/terryandann/author/Terry Aney.aspx"&gt;Terry Aney&lt;/a&gt; 的朋友在《&lt;a href="http://www.aneyfamily.com/terryandann/post/2008/04/Batch-Updates-and-Deletes-with-LINQ-to-SQL.aspx"&gt;Batch Updates and Deletes with LINQ to SQL&lt;/a&gt;》这篇博文中解决了这个问题。使用他提供的UpdateBatch 方法生成的 Update SQL 是：&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;UPDATE &lt;/span&gt;[dbo]&lt;span style="color: gray"&gt;.&lt;/span&gt;[Orders]&#xD;
    &lt;span style="color: blue"&gt;SET &lt;/span&gt;[ShippedDate] &lt;span style="color: gray"&gt;= &lt;/span&gt;@p1&#xD;
&lt;span style="color: blue"&gt;FROM &lt;/span&gt;[dbo]&lt;span style="color: gray"&gt;.&lt;/span&gt;[Orders] &lt;span style="color: blue"&gt;AS &lt;/span&gt;j0 &lt;span style="color: gray"&gt;INNER JOIN (&#xD;
    &lt;/span&gt;&lt;span style="color: blue"&gt;SELECT &lt;/span&gt;[t0]&lt;span style="color: gray"&gt;.&lt;/span&gt;[OrderID]&#xD;
    &lt;span style="color: blue"&gt;FROM &lt;/span&gt;[dbo]&lt;span style="color: gray"&gt;.&lt;/span&gt;[Orders] &lt;span style="color: blue"&gt;AS &lt;/span&gt;[t0]&#xD;
        &lt;span style="color: gray"&gt;LEFT OUTER JOIN &lt;/span&gt;[dbo]&lt;span style="color: gray"&gt;.&lt;/span&gt;[Customers] &lt;span style="color: blue"&gt;AS &lt;/span&gt;[t1] &lt;span style="color: blue"&gt;ON &lt;/span&gt;[t1]&lt;span style="color: gray"&gt;.&lt;/span&gt;[CustomerID] &lt;span style="color: gray"&gt;= &lt;/span&gt;[t0]&lt;span style="color: gray"&gt;.&lt;/span&gt;[CustomerID]&#xD;
    &lt;span style="color: blue"&gt;WHERE &lt;/span&gt;[t1]&lt;span style="color: gray"&gt;.&lt;/span&gt;[CustomerID] &lt;span style="color: gray"&gt;= &lt;/span&gt;@p0&#xD;
&lt;span style="color: gray"&gt;) &lt;/span&gt;&lt;span style="color: blue"&gt;AS &lt;/span&gt;j1 &lt;span style="color: blue"&gt;ON &lt;/span&gt;&lt;span style="color: gray"&gt;(&lt;/span&gt;j0&lt;span style="color: gray"&gt;.&lt;/span&gt;[OrderID] &lt;span style="color: gray"&gt;= &lt;/span&gt;j1&lt;span style="color: gray"&gt;.&lt;/span&gt;[OrderID]&lt;span style="color: gray"&gt;)&#xD;
&#xD;
&lt;/span&gt;&lt;span style="color: green"&gt;-- @p0: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [Bruce]&#xD;
-- @p1: Input DateTime (Size = 0; Prec = 0; Scale = 0) [2010/8/11 19:51:59]&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;虽然跟我刚才手写的SQL略有不同，但 Update 的逻辑是对的。有兴趣的朋友不妨试试，Terry Aney在他的文章里有很详尽的介绍，这里不再详述。&lt;/p&gt;&#xD;
&lt;p&gt;相关博文：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.aneyfamily.com/terryandann/post/2008/04/Batch-Updates-and-Deletes-with-LINQ-to-SQL.aspx"&gt;Batch Updates and Deletes with LINQ to SQL&lt;/a&gt;&lt;br&gt;&lt;a href="http://www.aneyfamily.com/terryandann/post/2008/04/LINQ-to-SQL-Batch-UpdatesDeletes-Fix-for-Could-not-translate-expression.aspx"&gt;LINQ to SQL Batch Updates/Deletes: Fix for 'Could not translate expression'&lt;/a&gt;&lt;br&gt;&lt;a href="http://www.aneyfamily.com/terryandann/post/2008/12/Ive-Left-Query-Analyzer-Hell-For-LINQPad-Heaven.aspx"&gt;I've Left Query Analyzer Hell For LINQPad Heaven&lt;/a&gt;&#xD;
&lt;p&gt;&lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;总结&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Linq To SQL 有很多地方值得探索的，Expression Tree 是探索的基础， 嘿嘿！&#xD;
&lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;完整代码&lt;/strong&gt;&lt;/font&gt;（内含&lt;strong&gt;Terry Aney&lt;/strong&gt; 的代码）&#xD;
&lt;p&gt;&lt;a href="http://files.cnblogs.com/coolcode/Linq2SQL%e6%89%b9%e9%87%8f%e6%9b%b4%e6%96%b0.rar"&gt;Linq2SQL批量更新.rar&lt;/a&gt;&lt;img src="http://www.cnblogs.com/coolcode/aggbug/1775337.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/coolcode/archive/2010/07/11/LinqToSQL_Batch_Update.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/coolcode/archive/2010/05/26/dotNet4_Expression_Tree_Beginning_4_Primes.html</id><title type="text">.Net4 Expression Tree 入门(4): 求N以内的所有质数</title><summary type="text">前面已经介绍了.Net4 Expression Tree的分支与循环，是时候综合起来写一个稍微复杂一点的实例了。求N以内的所有质数你是否也因为Expression 里没有for这个方法而感到不爽？一切循环都得改成loop这种形式？Expression构建是不是很麻烦罗嗦？为什么Expression一切方法皆是static的...</summary><published>2010-05-26T06:59:00Z</published><updated>2010-05-26T06:59:00Z</updated><author><name>CoolCode</name><uri>http://www.cnblogs.com/coolcode/</uri></author><link rel="alternate" href="http://www.cnblogs.com/coolcode/archive/2010/05/26/dotNet4_Expression_Tree_Beginning_4_Primes.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/coolcode/archive/2010/05/26/dotNet4_Expression_Tree_Beginning_4_Primes.html"/><content type="html">&lt;p&gt;&lt;/p&gt; &lt;p&gt;目录&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.cnblogs.com/coolcode/archive/2010/05/17/dotNet4_Expression_Tree_Beginning_1_HelloWorld.html"&gt;.Net4 Expression Tree 入门(1): Hello World!&lt;/a&gt;  &lt;p&gt;&lt;a href="http://www.cnblogs.com/coolcode/archive/2010/05/17/dotNet4_Expression_Tree_Beginning_2_IfThen_SwitchCase.html"&gt;.Net4 Expression Tree 入门(2): IfThen, SwitchCase&lt;/a&gt;  &lt;p&gt;&lt;a href="http://www.cnblogs.com/coolcode/archive/2010/05/17/dotNet4_Expression_Tree_Beginning_3_Loop.html"&gt;.Net4 Expression Tree 入门(3): Loop 循环&lt;/a&gt;  &lt;p&gt;&lt;/p&gt; &lt;p&gt;前面已经介绍了.Net4 Expression Tree的分支与循环，是时候综合起来写一个稍微复杂一点的实例了。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;求N以内的所有质数&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;一般的写法&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; GetPrimes_SimpleMethod(&lt;span style="color: blue"&gt;int &lt;/span&gt;to)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;res = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;();&#xD;
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;n = 2; n &amp;lt;= to; n++)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;bool &lt;/span&gt;found = &lt;span style="color: blue"&gt;false&lt;/span&gt;;&#xD;
&#xD;
        &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;d = 2; d &amp;lt;= &lt;span style="color: #2b91af"&gt;Math&lt;/span&gt;.Sqrt(n); d++)&#xD;
        {&#xD;
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(n % d == 0)&#xD;
            {&#xD;
                found = &lt;span style="color: blue"&gt;true&lt;/span&gt;;&#xD;
                &lt;span style="color: blue"&gt;break&lt;/span&gt;;&#xD;
            }&#xD;
        }&#xD;
&#xD;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(!found)&#xD;
            res.Add(n);&#xD;
    }&#xD;
    &lt;span style="color: blue"&gt;return &lt;/span&gt;res;&#xD;
}&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;暂且不用考虑以上算法的时间复杂度、性能什么的，因为只是为了学习 &lt;a href="http://www.cnblogs.com/coolcode/archive/2010/05/26/Why_I_need_to_learn_Expression_Tree.html" target="_blank"&gt;Expression Tree&lt;/a&gt; 而已。&lt;a href="http://www.cnblogs.com/coolcode/archive/2010/05/17/dotNet4_Expression_Tree_Beginning_3_Loop.html" target="_blank"&gt;之前&lt;/a&gt;都说过，Expression 里是没有For这些常用方法的，只有Loop，因此为了更方便构造 &lt;a href="http://www.cnblogs.com/coolcode/archive/2010/05/26/Why_I_need_to_learn_Expression_Tree.html" target="_blank"&gt;Expression Tree&lt;/a&gt;， 需要对上面代码稍微修改成没for的形式。&lt;/p&gt;&#xD;
&lt;p&gt;如&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;n = 2; n &amp;lt;= to; n++)&#xD;
{&#xD;
    &lt;font color="#008000"&gt;// do sth…&lt;/font&gt;&#xD;
}&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;改成 while形式：&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;int &lt;/span&gt;n = 2;&#xD;
&lt;span style="color: blue"&gt;while &lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(!(n &amp;lt;= to))&#xD;
        &lt;span style="color: blue"&gt;break&lt;/span&gt;;&#xD;
    &lt;font color="#008000"&gt;// do sth…&lt;/font&gt;&#xD;
    n++;&#xD;
}&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;strong&gt;求N以内的所有质数的“NoFor” 写法&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;【纯粹是为了更方便构造 &lt;a href="http://www.cnblogs.com/coolcode/archive/2010/05/26/Why_I_need_to_learn_Expression_Tree.html" target="_blank"&gt;Expression Tree&lt;/a&gt;，否则相信没人用&lt;font color="#ff0000"&gt;while(true)&lt;/font&gt;这样写法】&lt;/p&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; GetPrimes_NoFor(&lt;span style="color: blue"&gt;int &lt;/span&gt;to)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;res = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;();&#xD;
    &lt;span style="color: blue"&gt;int &lt;/span&gt;n = 2;&#xD;
    &lt;span style="color: blue"&gt;while &lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)&#xD;
    {&#xD;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(!(n &amp;lt;= to))&#xD;
            &lt;span style="color: blue"&gt;break&lt;/span&gt;;&#xD;
        &lt;span style="color: blue"&gt;bool &lt;/span&gt;found = &lt;span style="color: blue"&gt;false&lt;/span&gt;;&#xD;
&#xD;
        &lt;span style="color: blue"&gt;int &lt;/span&gt;d = 2;&#xD;
        &lt;span style="color: blue"&gt;while &lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)&#xD;
        {&#xD;
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(!(d &amp;lt;= &lt;span style="color: #2b91af"&gt;Math&lt;/span&gt;.Sqrt(n)))&#xD;
                &lt;span style="color: blue"&gt;break&lt;/span&gt;;&#xD;
&#xD;
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(n % d == 0)&#xD;
            {&#xD;
                found = &lt;span style="color: blue"&gt;true&lt;/span&gt;;&#xD;
                &lt;span style="color: blue"&gt;break&lt;/span&gt;;&#xD;
            }&#xD;
&#xD;
            d++;&#xD;
        }&#xD;
&#xD;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(!found)&#xD;
            res.Add(n);&#xD;
&#xD;
        n++;&#xD;
    }&#xD;
    &lt;span style="color: blue"&gt;return &lt;/span&gt;res;&#xD;
}&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;上述代码与表达式的对比列表&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;table border="1" cellspacing="0" cellpadding="2" width="800"&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="400"&gt;&#xD;
&lt;p align="center"&gt;&lt;font size="2"&gt;&lt;strong&gt;原始代码&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;/td&gt;&#xD;
&lt;td valign="top" width="400"&gt;&#xD;
&lt;p align="center"&gt;&lt;strong&gt;&lt;font size="2"&gt;表达式&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;res = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;(); &lt;/td&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;pre &gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Assign(&#xD;
    res,&#xD;
    &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.New(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;))&#xD;
)&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;span style="color: blue"&gt;int &lt;/span&gt;n = 2; &lt;/td&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;pre &gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Assign(&#xD;
    n,&#xD;
    &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Constant(2)&#xD;
)&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;span style="color: blue"&gt;&lt;pre &gt;&lt;span style="color: blue"&gt;while &lt;/span&gt;(&lt;span style="color: blue"&gt;true&lt;/span&gt;)&#xD;
{&#xD;
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(!(n &amp;lt;= to))&#xD;
        &lt;span style="color: blue"&gt;break&lt;/span&gt;;&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;pre &gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Loop(&#xD;
    &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Block(&#xD;
        &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.IfThen(&#xD;
            &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Not(&#xD;
                &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.LessThanOrEqual(&#xD;
                    n,&#xD;
                    to&#xD;
                )&#xD;
            ),&#xD;
            &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Break(breakOuter)&#xD;
        )&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;span style="color: #2b91af"&gt;Math&lt;/span&gt;.Sqrt(n)&lt;/td&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;pre &gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Call(&#xD;
    &lt;span style="color: blue"&gt;null&lt;/span&gt;,&#xD;
    &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Math&lt;/span&gt;).GetMethod(&lt;span style="color: #a31515"&gt;"Sqrt"&lt;/span&gt;),&#xD;
    &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Convert(&#xD;
        n,&#xD;
        &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;double&lt;/span&gt;)&#xD;
    )&#xD;
)&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="400"&gt;d++;&lt;/td&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;pre &gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.PostIncrementAssign(d)&#xD;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="400"&gt;res.Add(n);&lt;/td&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;pre &gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Call(&#xD;
    res,&#xD;
    &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;).GetMethod(&lt;span style="color: #a31515"&gt;"Add"&lt;/span&gt;),&#xD;
    n&#xD;
)&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;最终构建表达式的代码很长，有兴趣的不妨自己试着写写，这里不贴上来，可以参考&lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2009/08/11/statement-trees-with-less-pain-follow-up-on-system-linq-expressions-v4-0.aspx" target="_blank"&gt;这篇外文&lt;/a&gt; 《&lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2009/08/11/statement-trees-with-less-pain-follow-up-on-system-linq-expressions-v4-0.aspx" target="_blank"&gt;STATEMENT TREES WITH LESS PAIN – FOLLOW-UP ON SYSTEM.LINQ.EXPRESSIONS V4.0&lt;/a&gt;》。&lt;/p&gt;&#xD;
&lt;p&gt;你是否也因为Expression 里没有for这个方法而感到不爽？一切循环都得改成loop这种形式？Expression构建是不是很麻烦罗嗦？为什么Expression一切方法皆是static的…等等。&lt;/p&gt;&#xD;
&lt;p&gt;如果改成下面这种形式会不会好点？&lt;/p&gt;&#xD;
&lt;table border="1" cellspacing="0" cellpadding="2" width="802"&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="400"&gt;&#xD;
&lt;p align="center"&gt;&lt;font size="2"&gt;&lt;strong&gt;原始代码&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;/td&gt;&#xD;
&lt;td valign="top" width="400"&gt;&#xD;
&lt;p align="center"&gt;&lt;strong&gt;&lt;font size="2"&gt;表达式&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;res = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;(); &lt;/td&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;pre &gt;res.Assign(&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.New(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;)))&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;span style="color: blue"&gt;int &lt;/span&gt;n = 2; &lt;/td&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;pre &gt;n.Assign(2)&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="400"&gt;n ++;&lt;/td&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;pre &gt;n.PostIncrementAssign()&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;n = 2; n &amp;lt;= to; n++) &lt;/td&gt;&#xD;
&lt;td valign="top" width="400"&gt;&lt;pre &gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.For(n, n.Assign(2), n &amp;lt;= to, n.PostIncrementAssign()&#xD;
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="400"&gt;res.Add(n);&lt;/td&gt;&#xD;
&lt;td valign="top" width="400"&gt;res.Method("Add", n)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这样会不会更简洁？欢迎作进一步交流。我会在下一篇随笔里分析如何实现以上形式的写法。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/coolcode/aggbug/1744462.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/coolcode/archive/2010/05/26/dotNet4_Expression_Tree_Beginning_4_Primes.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
