[转载]T-SQL查询进阶--深入浅出视图

mikel阅读(834)

[转载]T-SQL查询进阶–深入浅出视图 – CareySon – 博客园.

简介

视图可以看作定义在SQL Server上的虚拟表.视图正如其名字的含义一样,是另一种查看数据的入口.常规视图本身并不存储实际的数据,而仅仅存储一个Select语句和所涉及表的metadata.

视图简单的理解如下:

5

通过视图,客户端不再需要知道底层table的表结构及其之间的关系。视图提供了一个统一访问数据的接口。

为什么要使用视图(View)

从而我们不难发现,使用视图将会得到如下好处:

  • 视图隐藏了底层的表结构,简化了数据访问操作
  • 因为隐藏了底层的表结构,所以大大加强了安全性,用户只能看到视图提供的数据
  • 使用视图,方便了权限管理,让用户对视图有权限而不是对底层表有权限进一步加强了安全性
  • 视图提供了一个用户访问的接口,当底层表改变后,改变视图的语句来进行适应,使已经建立在这个视图上客户端程序不受影响

视图(View)的分类

视图在SQL中可以分为三类

  1. 普通视图(Regular View)
  2. 索引视图(Indexed View)
  3. 分割视图(Partitioned View)

下面从这几种视图类型来谈视图

普通视图(Rugular View)

普通视图由一个Select语句所定义,视图仅仅包含其定义和被引用表的metadata.并不实际存储数据。MSDN中创建视图的模版如下:

CREATE VIEW [ schema_name . ] view_name [ (column [ ,...n ] ) ] 
[ WITH <view_attribute> [ ,...n ] ] 
AS select_statement 
[ WITH CHECK OPTION ] [ ; ]

<view_attribute> ::= 
{
    [ ENCRYPTION ]
    [ SCHEMABINDING ]
    [ VIEW_METADATA ]     }

参数还是比较少的,现在解释一下上面的参数:

ENCRYPTION:视图是加密的,如果选上这个选项,则无法修改.创建视图的时候需要将脚本保存,否则再也不能修改了

SCHEMABINDING:和底层引用到的表进行定义绑定。这个选项选上的话,则视图所引用到的表不能随便更改构架(比如列的数据类型),如果需要更改底层表构架,则先drop或者alter在底层表之上绑定的视图.

VIEW_METADATA:这个是个很有意思的选项.正如这个选项的名称所指示,如果不选择,返回给客户端的metadata是View所引用表的 metadata,如果选择了这个选项,则返回View的metadata.再通俗点解释,VIEW_METADATA可以让视图看起来貌似表一样。 View的每一个列的定义等直接告诉客户端,而不是所引用底层表列的定义。

WITH Check Option:这个选项用于更新数据做限制,下面会在通过视图更新数据一节解释.

当然了,创建视图除了需要符合上面的语法规则之外,还有一些规则需要遵守:

  • 在View中,除非有TOP关键字,否则不能用Order By子句(如果你一意孤行要用Order by,这里有个hack是使用Top 100 percent…..)
  • View在每个Schema中命名必须独一无二
  • View嵌套不能超过32层(其实实际工作中谁嵌套超过两层就要被打PP了-.-)
  • Compute,compute by,INTO关键字不允许出现在View中
  • View不能建立在临时表上
  • View不能对全文索引进行查询

建立View一个简单的例子:

CREATE VIEW v_Test_View1
AS
SELECT TOP 100 * FROM HumanResources.Employee

视图建立完成后,就可以像访问表一样访问视图了:

SELECT * FROM v_Test_View1

在Management studio中,我创建视图的时候更喜欢用这样一种方法,将会便捷很多:

6

7

索引视图(Indexed View)

在谈到索引视图之前,我突然想起以前看过的一个漫画.话说咱们高端产品买不起,但是省吃俭用攒点钱买个IPhone装装高端总还是可以的吧:

1

其实索引视图也很类似,在普通的视图的基础上,为视图建立唯一聚集索引,这时这个视图就变成了索引视图.套用上面漫画的公式:视图+聚集索引=索引视图

索引视图可以看作是一个和表(Table)等效的对象!

SQL Server中的索引视图和Oracle中的Materialized View是一个概念.想要理解索引视图,必须先理解聚集索引。聚集索引简单来说理解成主键,数据库中中的数据按照主键的顺序物理存储在表中,就像新华字 典,默认是按照ABCD….这样的方式进行内容设置。ABCD….就相当于主键.这样就避免了整表扫描从而提高了性能.因此一个表中只能有一个聚集索引。

对于索引视图也是,为一个视图加上了聚集索引后。视图就不仅仅再是select语句和表的metadata了,索引视图会将数据物理存在数据库中,索引视图所存的数据和索引视图中所涉及的底层表保持同步。

理解了索引视图的原理之后,我们可以看出,索引视图对于LDAP这种大量数据分析和查询来说,性能将会得到大幅提升。尤其是索引视图中有聚合函数,涉及大 量高成本的JOIN,因为聚合函数计算的结果物理存入索引视图,所以当面对大量数据使用到了索引视图之后,并不必要每次都进行聚合运算,这无疑会大大提升 性能.

而同时,每次索引视图所涉及的表进行Update,Insert,Delete操作之后,SQL Server都需要标识出改变的行,让索引视图进行数据同步.所以LDTP这类增删改很多的业务,数据库需要做大量的同步操作,这会降低性能。

谈完了索引视图的基本原理和好处与坏处之后,来看看在SQL Server中的实现:

在SQL Server中实现索引视图是一件非常,简单的事,只需要在现有的视图上加上唯一聚集索引.但SQL Server对于索引视图的限制却使很多DBA对其并不青睐:

比如:

  • 索引视图涉及的基本表必须ANSI_NULLS设置为ON
  • 索引视图必须设置ANSI_NULLS和QUOTED_INDETIFIER为ON
  • 索引视图只能引用基本表
  • SCHEMABINDING必须设置
  • 定义索引视图时必须使用Schema.ViewName这样的全名
  • 索引视图中不能有子查询
  • avg,max,min,stdev,stdevp,var,varp这些聚合函数不能用

………………

还有更多…就不一一列举了,有兴趣的请自行Google之.

下面我来通过一个例子来说明索引视图:

假设在adventureWorks数据库中,我们有一个查询:

SELECT p.Name,s.OrderQty
FROM Production.Product p
 inner join Sales.SalesOrderDetail s
ON p.ProductID=s.ProductID

这个查询的执行计划:

8before

这时,我建立视图并在这个视图上建立唯一聚集索引:

--建立视图
CREATE VIEW v_Test_IndexedView
WITH SCHEMABINDING
AS
SELECT p.Name,s.OrderQty,s.SalesOrderDetailID
FROM Production.Product p
 inner join Sales.SalesOrderDetail s
ON p.ProductID=s.ProductID
GO
--在视图上建立索引
CREATE UNIQUE CLUSTERED INDEX indexedview_test1
ON v_Test_IndexedView(SalesOrderDetailID)

接下来,套用刘谦的台词:见证奇迹的时刻到了,我们再次执行之前的查询:

8after

从上面这个例子中,可以体会到索引视图的强大威力,即使你的查询语句中不包含这个索引视图,查询分析器会自动选择这个视图,从而大大的提高了性能.当然, 这么强力的性能,只有在SQL SERVER企业版和开发版才有哦(虽然我见过很多SQL Server的开发人员让公司掏着Enterprise版的钱,用着Express版的功能……)

分割视图(Partitioned View)

分割视图其实从微观实现方式来说,整个视图所返回的数据由几个平行表(既是几个表有相同的表结构,也就是列和数据类型,但存储的行集合不同)进行UNION连接(对于UNION连接如果不了解,请看我之前的博文)所获得的数据集.

分割视图总体上可以分为两种:

1.本地分割视图(Local Partitioned View)

2.分布式分割视图(Distributed Partitioned View)

因为本地分割视图仅仅是为了和SQL Server 2005之前的版本的一种向后兼容,所以这里仅仅对分布式分割视图进行说明.

分布式分割视图其实是将由几个由不同数据源或是相同数据源获得的平行数据集进行连接所获得的,一个简单的概念图如下:

2

上面的视图所获得的数据分别来自三个不同数据源的表,每一个表中只包含四行数据,最终组成了这个分割视图.

使用分布式分割视图最大的好处就是提升性能.比如上面的例子中,我仅仅想取得ContactID为8这位员工的信息,如果通过分布式视图获取的话,SQL Server可以非常智能的仅仅扫描包含ContactID为8的表2,从而避免了整表扫描。这大大减少了IO操作,从而提升了性能.

这里要注意的是,分布式分割视图所涉及的表之间的主键不能重复,比如上面的表A ContactID是1-4,则表B的ContactID不能是2-8这个样子.

还有一点要注意的是,一定要为分布式分割索引的主键加Check约束,从而让SQL Server的查询分析器知道该去扫描哪个表,下面来看个例子.

在微软示例数据库AdventureWorks数据库,我通过ContactID从前100行和100-200行的数据分别存入两个表,Employee100和Employee200,代码如下:

--create Employee100
SELECT TOP 100 * INTO Employee100
FROM HumanResources.Employee 
ORDER BY EmployeeID
--create Employee200
SELECT *  INTO Employee200
FROM 
(SELECT TOP 100 *
FROM HumanResources.Employee 
WHERE EmployeeID NOT IN (SELECT TOP 100 EmployeeID FROM HumanResources.Employee ORDER BY EmployeeID)
ORDER BY HumanResources.Employee.EmployeeID)AS e

这时来建立分布式分割视图:

CREATE VIEW v_part_view_test
AS
SELECT * FROM Employee100
UNION 
SELECT * FROM Employee200

这时我们对这个索引进行查询操作:

SELECT * FROM v_part_view_test
WHERE EmployeeID=105

下面是执行计划:

3

通过上图可以看出,通过这种分割的方式,执行计划仅仅是扫描Employee200,从而避免了扫描所有数据,这无疑提升了性能.

所以,当你将不同的数据表之间放到不同的服务器或是使用RAID5磁盘阵列时,分布式分割视图则进一步会提升查询性能.

使用分布式分割视图能够在所有情况下都提升性能吗?那妥妥的不可能.使用这种方式如果面对的查询包含了聚合函数,尤其是聚合函数中还包含 distinct。或是不加where条件进行排序.那绝对是性能的杀手。因为聚合函数需要扫描分布式分割视图中所有的表,然后进行UNION操作后再进 行运算.

通过视图(View)更新数据

通过视图更新数据是我所不推荐的.因为视图并不能接受参数.我更推荐使用存储过程来实现.

使用View更新数据和更新Table中数据的方式完全一样(前面说过,View可以看作是一个虚拟表,如果是索引视图则是具体的一张表)

通过视图来更新数据需要注意以下几点

1.视图中From子句之后至少有一个用户表

2.View的查询无论涉及多少张表,一次只能更新其中一个表的数据

3.对于表达式计算出来的列,常量列,聚合函数算出来的列无法更新

4.Group By,Having,Distinct关键字不能影响到的列不能更新

这里说一下创建View有一个WITH Check Option选项,如果选择这个选项,则通过View所更新的数据必须符合View中where子句所限定的条件,比如:

我创建一个View:

4

视图(View)中的几个小技巧

1.通过视图名称查到视图的定义

SELECT * FROM sys.sql_modules
WHERE object_id=OBJECT_ID('视图名称')

2.前面说过,普通视图仅仅存储的是select语句和所引用表的metadata,当底层表数据改变时,有时候视图中表的metadata并没有及时同步,可以通过如下代码进行手动同步

EXEC sp_refreshview 视图名称

视图(View)的最佳实践

这是我个人一些经验,欢迎补充

  • 一定要将View中的Select语句性能调到最优(貌似是废话,不过真理都是废话…)
  • View最好不要嵌套,如果非要嵌套,最多只嵌套一层
  • 能用存储过程和自定义函数替代View的,尽量不要使用View,存储过程会缓存执行计划,性能更优,限制更少
  • 在分割视图上,不要使用聚合函数,尤其是聚合函数还包含了Distinct
  • 在视图内,如果Where子句能加在视图内,不要加在视图外(因为调用视图会返回所有行,然后再筛选,性能杀手,如果你还加上了order by…..)

总结

文中对视图的三种类型进行了详解.每种视图都有各自的使用范围,使用得当会将性能提升一个档次,而使用不当反而会拖累性能.

我想起一句名言:“everything has price,always trade-off”…..

[转载]ASP.NET MVC3 20个秘方-(15)使用CAPTCHA去防止恶意软件自动提交评论(防灌水)

mikel阅读(945)

[转载]【译】MVC3 20个秘方-(15)使用CAPTCHA去防止恶意软件自动提交评论(防灌水) – 技术弟弟 – 博客园.

问题

有种不太幸运的情况,有人用自动程序去提交表单,在整个互联网中造成大量的垃圾。为了防止这种情况的方法之一,是使用一个验证码—CAPTCHA:全自动区分计算机和人类的图灵测试,这迫使用户把生成的文字输入到文本框。

(译者:CAPTCHA是一种更人性化的验证码,可以通过视觉和听觉来区分post的请求是人类还是计算机发出的)

解决方案

NuGet安装ASP.NET Web Helpers Library 从而在BookCommentsController实现防止而已添加书评的功能。

讨论

需要安装一个新的类包,使在表单上应用CAPTCHA成为可能。微软已经创建了一个NuGet web helpers 类包含了CAPTCHA,让我们很容易实施并且验证用户输入的CAPTCHA。先打开MVC项目,在vs中选择Tools→LibraryPackage Manager→Add Library Package Reference。点击左边的Online,在第一页的下方您就可以发现 ASP.NET web helpers Library。点击安装。

在我们的例子里。那些自动发送post请求的软件一般会用在图书评论上。所以是这里最完美的添加CAPTCHA的地方。在开始之前你必须在RECAPTCHA website为你的域名注册。(译者:一般要用一个gmail账户。我们使用自己已有的或者重新注册一个,在这里由于我们的项目是在本机练习使用的,我就为我的localhost注册)。注册成功之后你可以得到一个公钥(public key)和一个私钥(private key)。

提示:如果你不使用Ajax去包含CAPTCHA,你可以通过以下两行代码改变你的view:

@using Microsoft.Web.Helpers;
@ReCaptcha.GetHtml("<你的公钥>", "<你的私钥>")

一旦配置完成了,是时候开始更新我们的代码了。我们需要在BookComments/Index view里做一些小更改。这个view是前一段创建的,用于使用ajax提交书评。这个Ajax需要更新成:当请求完毕,调用JavaScript函数去 显示CAPTCHA按钮。代码如下:

@model IEnumerable<MvcApplication.Models.BookComment>
@{
    ViewBag.Title = "Index";
}
<h2>
    Index</h2>
<p>
    @Ajax.ActionLink("Create New", "Create", new
{
    BookId = ViewBag.BookId
},
new AjaxOptions { UpdateTargetId = "AddComment" })
</p>
<div id="AddComment">
</div>
<script type="text/javascript" src=
"http://www.google.com/recaptcha/api/js/recaptcha_ajax.js">
</script>
<script type="text/javascript">
    function DisplayCaptcha() {
        Recaptcha.destroy();
        Recaptcha.create("6Le27coSAAAAAK8KqpUIGvz3qTDXGa9ud9Xst4yY", "captcha", {});//你的公钥

    }
</script>
<table>
    <tr>
        <th>
            Comment
        </th>
        <th>
            Created
        </th>
    </tr>
    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Comment)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Created)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Book.Title)
            </td>
        </tr>
    }
</table>

现在,去更新BookComments/create view 。首先添加一个地点去展示CAPTCHA.然后添加一个新的HTML 错误消息,当他们输入错误的验证码时,会提示错误。最后在ReloadComment  JavaScript 函数里更改代码成不自动reload 书评(仅仅当没错的时候才reload)。

@model MvcApplication.Models.BookComment
@{
    ViewBag.Title = "Create";
}
<h2>
    Create</h2>
@section JavascriptAndCSS {
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")"
type="text/javascript"></script>
    <script src="
@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"
type="text/javascript"></script>
}
<script type="text/javascript">
    function ReloadComments() {
        var reload = "@ViewBag.RefreshComments";
        if (reload == "False") {
            DisplayCaptcha();
        } else {
            $("#Comments").load("/BookComments/Index?BookId=@ViewBag.BookId");
        }
    }
</script>
@using (Ajax.BeginForm(new AjaxOptions
{
    UpdateTargetId = "AddComment",
    OnComplete = "ReloadComments"
}))
{
    @Html.Hidden("BookId", (int)ViewBag.BookId);
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>BookComment</legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.Comment)
        </div>
        <div class="editor-field">
            @Html.TextAreaFor(model => model.Comment)
            @Html.ValidationMessageFor(model => model.Comment)
        </div>
        <div class="editor-label">
            Are you human?
        </div>
        <div class="editor-field">
            <div id="captcha">
            </div>
            @Html.ValidationMessage("Captcha")
        </div>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

最后我们要更新BookCommentsController 去验证输入的CAPTCHA。如果验证不合法,我们就把错误消息添加到ModelState里去,view把它展示出来。

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication.Models;
using Microsoft.Web.Helpers;
using MvcApplication.Models;
namespace MvcApplication.Controllers
{
    public class BookCommentsController : Controller
    {
        private BookDBContext db = new BookDBContext();
        //
        // GET: /BookComments/
        public ActionResult Index(int BookId)
        {
            ViewBag.BookId = BookId;
            var bookcomments = db.BookComments.Include(
            b => b.Book).Where(b => b.BookId == BookId);
            return PartialView(bookcomments.ToList());
        }
        //
        // GET: /BookComments/Create
        public ActionResult Create(int BookId)
        {
            ViewBag.BookId = BookId;
            ViewBag.RefreshComments = false;
            return PartialView();
        }
        //
        // POST: /BookComments/Create
        [HttpPost]
        public ActionResult Create(BookComment bookcomment)
        {
            ViewBag.RefreshComments = false;
            var captchaSuccess = ReCaptcha.Validate(
            "6Le27coSAAAAAM6kZnXU8m1j9");//你的私钥

            if (ModelState.IsValid && captchaSuccess)
            {
                bookcomment.Created = DateTime.Now;
                db.BookComments.Add(bookcomment);
                db.SaveChanges();
                ViewBag.RefreshComments = true;
            }
            // if captcha failed add error message
            if (!captchaSuccess)
            {
                ModelState.AddModelError("Captcha",
                "Invalid CAPTCHA");
            }
            ViewBag.BookId = bookcomment.BookId;
            return PartialView(bookcomment);
        }
        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}

(译者:下图是我实践之后的截图,不知道这个CAPTCHA的背景样式是否能自定义,如果可以的话就太酷了!)

[转载]16个wordpress博客中使用的Google服务和应用

mikel阅读(1421)

[转载]16个wordpress博客中使用的Google服务和应用 – gbin1 – 博客园.

Google 提供了很多不错的用户端服务和应用,虽然最初是一个搜索引擎,今天Google几乎为每一个用户提供解决方案。当为了满足需求的时候,Google并不忘 记满足web开发人员和设计人员的需求。在这篇文章中,我们将了解一下Google提供了那些主要的服务,并且如何应用到wordpress中的。

16个wordpress博客中使用的Google服务和应用

1. Google自定义搜索

Google自定义搜索帮 助网站创建了一个自制定的搜索引擎。帮助你构建你的核心功能,帮助你搜索整个网站,部分网站甚至是多个站点。同时你也可以使用Google adsense来帮助你显示广告到你的搜索结果中,当然你可以使用付费版本,这样可以去掉所有的广告(100美元/年),给用户提供更好的搜索体验。

16个wordpress博客中使用的Google服务和应用

2. Goolge Web Fonts

Google Web Fonts可能是web设计及其开发人员最喜欢使用的功能之一。帮助网站设计人员在网站中使用非标准的字体。这些字体的目录可以让你很简单的执行CSS font-face技巧。

16个wordpress博客中使用的Google服务和应用

Google web fonts完全免费并且实现非常简单,你可以使用插件或者CSS的@import命令(在你的样式表中简单的使用字体名称即可),例如,

@import url(‘http://fonts.googleapis.com/css?family=Droid+Sans’);
#body { font: normal normal normal 14px/20px ‘Droid Sans’, Arial, sans-serif; }

3. Google Adsense/Adwords

如果你希望在你的网站中添加广告的话, Google adsense可能是最简单的方法。这里我们能狗找到很多的帮助你使用Google adsense赚钱的教程,numerous plugins帮助你在wordpress中添加Google Adsene。

16个wordpress博客中使用的Google服务和应用

使用Adwords,你可以使用关键字查找来找到指定关键自的搜索趋势

4. Goo.gl URL shortener

wordpress拥有它自己的URL缩写插件WP.me, 目前这个特性整合到JetPack中。 然而, Google宣称自己URL缩写工具是one of a kind, 而且, Google已经发布了它自己的URL缩写API。因此如果你没有开始使用这个,现在是你开始尝试的时候? 如果你想使用这个API,使用 excellent tutorial by konstantin kovshenin 帮助你快速的整合功能到你的wordpress。 如果你不希望自己开发代码,那么这里有很多插件你可以选择。

16个wordpress博客中使用的Google服务和应用

5. Feedburner

有谁不知道 Feedburner? 非常伟大的工具帮助你跟踪网站的变化, 订阅者的数量, 管理RSS及其email订阅,当然可以帮助你设置和调整你博客的feeds

16个wordpress博客中使用的Google服务和应用

6. Google Analytics

几乎所有人都使用Analytics!它是一个伟大的工具帮助你跟踪你的网站点击量,广告,参考网站及其其它功能。你可以定义指定的部分,然后查询你的网站那个部分最受欢迎。对于wordpress用户,Joost de Valk开发的Definitive wordpress Analytics可能是最受欢迎的Analytics插件。如果你不熟悉Analytics,你可以考虑学习一下这个教程: tutorial by KISSmetrics

16个wordpress博客中使用的Google服务和应用

7. Google Website Optimizer

Google Website Optimizer 帮助你执行测试来简单如果能帮助你提高网站的性能。 换句话说, 它能够帮助你执行分离式测试。

然而,非常高的操作要求,如果你寻找一个简单的解决方式, 你应该考虑一下 MAXA/B wordpress插件。

8. Google Libraries API

Google Libraries API 包含了一个能够应用到很多平台上的代码框架, 包括 wordpress。但是事实上这种说法背后的事实正如大家猜想的一样,经常提高Google libraries frameword比整合到wordpress的那个更快。最简单的方式来整合Google Libraries’s framework是使用一个插件, 但是如果你想更深入的话,你可以手动编写代码,使用如下代码行(个人来说建议你使用这些方法到自定义扩展或者插件):

<?php
wp_deregister_script(‘jquery’);
wp_register_script(‘jquery’, ‘http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js’);
wp_enqueue_script(‘query’);
?>

Code感谢: Frederick Townes

Google libraries API目前支持Chrome Frame, Dojo, Ext Core, JQueryJQuery UI, MooTools, protype, Script.aculo.us, SWFObject, Yahoo! user interface library(YUI), 并且Webfont loader。这里查看手册

9. Google Chrome Develoepr Tools

Google Chrome已经占有了10%的浏览器市场。 它也拥有自己的开发工具,堪比Firefox的Firebug。归功于Chrome浏览器的巨大流行, Chrome DT中提供的扩展也开始流行。
http://www.youtube.com/v/nOEw9iiopwI

10. Google Proejct hosting

Google Project Hosting允许你在线管理项目。类似于Github的管理操作。你可以自己管理项目,拥有2G的免费空间。并且提供子版本管理,项目Wiki及其问题管理和跟踪功能。 对于wordpress的用户来说, 许多重量级别的项目类似 Thematic 都选择 Google project hosting

16个wordpress博客中使用的Google服务和应用

11. Google Checkout

Google checkout是一个类似于paypal的功能。最好之处在于极好的和其它Google应用的整合,例如Adsense和Adwords。 缺点是,很多国家不支持

毫无疑问,整合Google Checkout作为支付方式的一个备选不是一个坏主义。对于WP用户来说,这里很多的插件帮助你整合Google checkout到你自己的网站,例如 Simple Google checkout或者LBAK google checkout.

12. Google Docs和Charts Tools

Google Docs是一个基于Web的办公室套件,允许你创建和分享文档,电子表格,演讲稿或者表单。你甚至可以和多个用户实时的编辑。
Google Docs可以插入wordpress。 使用类似的代码,你可以使用Google Chart Tools来创建互动图片

13. Google Maps

Google Maps可以说是无人不知。你可以使用multiple plugins来整合Google Maps到你的博客。最受欢迎的可能是MapPress.允许简单的快速整合地图到你的WP网站

16个wordpress博客中使用的Google服务和应用

14. YouTube

YouTube是另外一个非常流行的Google服务,允许你上传和分享视频。从博客的角度来看,你可以简单的上传视频到youtue,省去不菲的带宽。使用HTML5的特性,整合Youtube视频到你的网站将是一件非常简单的事情。直接输入URL就Ok了!

当然如果你想完全控制插入的视频,你需要使用类TubePressviper’s vidoe quicktags等插件

15. Google Reader

Google Reader是一个免费的RSS feed工具。如果你希望从你的RSS阅读面板保存内容,你可以添加一个“send to”的按钮到你的wordpress(缺省的话,这样的机制存在与Facebook, Twitter和其它一些网站,但不是一个WP网站)

16个wordpress博客中使用的Google服务和应用

你可能也在使用wordpress的”press This“功能,但是很不幸,这样行不通, Reader只接受完整的URL

这种情况下,我们将需要一个post一个目睹到press-this.php

为了达到这个目的,导航到Google reader的Setting下的”send to”标签,然后点击”create a custom link’.在URL字段,输入URL到你的网站,并且包括如下内容:

http://www.sample-website.com/wp-admin/press-this.php?u=${url}&t=${title}&s=${source}&v=2

确认你替换”sample-webisite”为你自己的网站。

16. Google summer of code

这不是一个扩展或者应用, Summer of code提供了一个非常不错的机会来做一些非凡的事情! wordpress自从2007开始就是一个积极的参加者,你可以在这里查看最近情况Codex

via 1stwebdesigner

欢迎访问GBin1.com

[转载]国外程序员推荐的免费编程书籍资源

mikel阅读(1839)

[转载]国外程序员推荐的免费编程书籍资源_IT新闻_博客园.

StackOverflow 上有位网友(xenoterracide)提问:

我正试着搜集整理一个可在网上免费阅读的计算机编程书籍列表。这些书可以是某种特定编程语言,也可以计算机方面通用书籍。网上有哪些免费可用的书籍呢?

下面是一些网友在回复中的推荐资源,其中有视频、大学课程、编程语言教程网站,由伯乐在线整理编译。

一、George Stocker 提供了一大串,分类如下:

Meta-Lists

How to Design Programs: An Introduction to Computing and Programming

25 Free Computer Science Ebooks

Free Tech Books

MindView Inc

Wikibooks: Programming

Cheat Sheets (Free)

CodePlex List of Free E-Books

Book Training – On Video!

Sofware Program Managers Network – Free EBooks

EBook Share @ linbai.info

FreeBooksClub.Net

Theassayer.org

O’Reilly’s Open Books Project

TechBooksForFree.com

Galileo Computing (德语)

Microsoft Press: Free E-Books

Graphics Programming 图形编程

GPU Gems

GPU Gems 2ch 8,14,18,29,30 as pdf

GPU Gems 3

Graphics Programming Black Book

ShaderX series

DirectX manual (draft)

Learning Modern 3D Graphics Programming (draft)

Language Agnostic

Object-Oriented Reengineering Patterns

Foundations of Programming

Computer Musings (由唐纳德·克努斯授课)

The Cathedral and the Bazaar

Patterns and Practices: Application Architecture Guide 2.0

Security Engineering

Digital Signal Processing For Engineers and Scientists

Getting Real

Structure and Interpretation of Computer Programs

Domain Driven Design Quickly

OO Design

Best Kept Secrets of Peer Code Review

NASA Software Measurement Handbook

NASA Manager Handbook for Software Development (PDF)

Introduction to Functional Programming (经典课程)

How to Design Programs

Guide to the Software Engineering Body of Knowledge

Online Course Materials

Algorithms (draft)

Data Structures and Algorithms

Essential Skills for Agile Development

Programming Languages: Application and Interpretation

Learn to Program

Patterns of Software: Tales from the Software Community (PDF)

How to write Unmaintainable Code

The Art of Unix ProgrammingUNIX 编程艺术

The Definitive Guide to Building Code Quality

How to Think Like a Computer Scientist

Planning Algorithms

Mathematical Logic – an Introduction (PDF)

An Introduction to the Theory of Computation

Developers Developers Developers Developers

Linkers and loaders

Let’s Build a Compiler

Producing Open Source Software

How to Write Parallel Programs

Don’t Just Roll the Dice

97 Things Every Programmer Should Know(这本书有中文版《程序员应该知道的97件事》)

How Computers Work

Introduction to Information Retrieval

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Matters Computational

Type Theory and Functional Programming

Getting started with Open source development (PDF)

Database Fundamentals (PDF)

Clever Algorithms

Summary of the GoF Design Patterns

Flow based Programming

Algorithms and Data-Structures (PDF)

Compiler Construction (PDF)

Project Oberon (PDF)

The Little Book of Semaphores

Essential Skills for Agile Development

I Am a Bug

Mining of Massive Datasets

Data-Intensive Text Processing with MapReduce (PDF)

Understanding IP Addressing: Everything you ever wanted to know (PDF)

Operating Systems and Middleware (PDF and LaTeX)

ASP.NET MVC

NerdDinner Walkthrough

Assembly Language 汇编语言

ProgrammingGroundUp (PDF)

Paul Carter’s Tutorial on x86 Assembly

Software optimization resources by Agner Fog

Bash

Advanced Bash-Scripting Guide

Lhunath’s Bash Guide

C / C++

The new C standard – an annotated reference

Matters Computational: Ideas, Algorithms, Source Code, by Jorg Arndt

The C book

Thinking in C++, Second Edition (《C++编程思想》)

C++ Annotations

Software optimization resources by Agner Fog

Introduction to Design Patterns in C++ with Qt 4 (PDF)

Object Oriented Programming in C (PDF)

Beej’s Guide to Network Programming

Learn C the hard way

Also see: The Definitive C++ Book Guide and List

C#

请参见下面 .NET 方面的

Clojure

Clojure Programming

ColdFusion

CFML In 100 Minutes

DB2

Getting started with IBM Data Studio for DB2 (PDF)

Getting started with IBM DB2 development (PDF)

Getting started with DB2 Express-C (PDF)

Delphi / Pascal

Essential Pascal Version 1 and 2

The Tomes of Delphi

Django

Djangobook.com

Erlang

Learn You Some Erlang For Great Good

Flex

Getting started with Adobe Flex (PDF)

F#

The F# Survival Guide

F Sharp Programming in Wikibooks

Forth

Starting Forth

Thinking Forth

Git

Pro Git

The Git Community Book

Git From The Bottom Up (PDF)

Grails

Getting Start with Grails

Haskell

Learn You a Haskell

Real World Haskell

HTML / CSS

Dive Into HTML5

HTML Dog Tutorials

Java

Sun’s Java Tutorials

Thinking in Java (《Java 编程思想》)

How to Think Like a Computer Scientist

Java Thin-Client Programming

OSGi in Practice (PDF)

Java 6 Tutorial (PDF)

JavaScript

Eloquent JavaScript

Crockford’s JavaScript

jQuery Fundamentals (starts with JavaScript basics)

Mozilla Developer Network’s JavaScript Guide

Essential Javascript & jQuery Design Patterns for Beginners

Latex

The Not So Short Introduction to LATEX (perfect for beginners 特别适合初学者)

Linux

Advanced Linux Programming

Lisp

A Gentle Introduction to Symbolic Computation (PDF)

Practical Common Lisp

On Lisp

ANSI Common Lisp

Common Lisp the Language, 2nd Edition

Successful Lisp

Let Over Lambda – 50 Years of Lisp

Natural Language Processing in Lisp

Lua

Programming In Lua (for v5 but still largely relevant)

Lua Programming Gems (不完全免费,但有很多免费的章节及代码)

Maven

Better Builds with Maven

Maven by Example

Maven: The Complete Reference

Repository Management with Nexus

Developing with Eclipse and Maven

Mercurial

Mercurial: The Definitive Guide

HGInit – Mercurial Tutorial by Joel Spolsky

Nemerle

See .NET below

.NET (C# / VB / Nemerle / Visual Studio)

C# School (covers C# 1.0 and 2.0)

Visual Studio Tips and Tricks (VS 2003-2005 only)

Entity Framework

Charles Petzold’s .NET Book 0

Threading in C#

C# Yellow Book (intro to programming)

C# Programming – Wikibook

C# Essentials

Data Structures and Algorithms with Object-Oriented Design Patterns in C#

Illustrated C# 2008 (.zip, dead link)

O’Reilly’s C# Pocket Reference Manual (dead link)

Nemerle

NoSQL

CouchDB: The Definitive Guide

The Little MongoDB Book

Oberon

Programming in Oberon (PDF)

Objective-C

The Objective-C Programming Language

OCaml

Unix System Programming in OCaml

Introduction to OCaml (PDF)

Oracle Server

Oracle’s Guides and Manuals

Oracle PL/SQL

PL/SQL Language Reference

PL/SQL Packages and Types Reference

Steven Feuerstein’s PL/SQL Obsession – Videos and Presentations

Parrot / Perl 6

Using Perl 6 (work in progress)

Perl

Higher-Order Perl

Perl The Hard Way

Extreme Perl

Perl Free Online EBooks (meta-list)

The Mason Book

Practical mod_perl

Beginning Perl

Embedding Perl in HTML with Mason

Perl & LWP

Perl for the Web

Web Client Programming with Perl

Modern Perl 5

PHP

Practical PHP Programming (wiki containing O’Reilly’s PHP In a Nutshell)

Zend Framework: Survive the Deep End

PowerShell

Mastering PowerShell

Prolog

Building Expert Systems in Prolog

Adventure in Prolog

Prolog Programming A First Course

Logic, Programming and Prolog (2ed)

Introduction to Prolog for Mathematicians

Learn Prolog Now!

Natural Language Processing in Prolog

Natural Language Processing Techniques in Prolog

Prolog techniques

Applications of Prolog

Simply logical

PostgreSQL

Practical PostgreSQL

Python

Dive Into Python

Dive Into Python 3

Byte of Python

Building Skills in Python Version 2.5

Python Free Online Ebooks (meta-list)

Python Bibliotheca

Think Python (PDF)

Data Structures and Algorithms in Python

How to Think Like a Computer Scientist: Learning with Python

Python for Fun

Invent Your Own Computer Games With Python

Learn Python The Hard Way

Thinking in Python

The Django Book

Snake Wrangling For Kids

Natural Language Processing with Python

R

The R Manuals

The R Language

R by example

Computational Statistics, Jeremy Penzer

Ruby

Programming Ruby

Why’s (Poignant) Guide to Ruby (mirror)

Mr. Neighborly’s Humble Little Ruby Book

Ruby Best Practices

MacRuby: The Definitive Guide

Learn Ruby the hard way

Ruby on Rails

Ruby on Rails Tutorial: Learn Rails By Example

Scala

Programming in Scala, First Edition

A Scala Tutorial for Java programmers (PDF)

Scala By Example (PDF)

Programming Scala

Xtrace (Github)

List (Github)

Pro Scala: Monadic Design Patterns for the Web

Exploring Lift (published earlier as “The Definitive Guide to Lift”, PDF)

Scheme

The Scheme Programming Language (Edition 4)

Smalltalk

Free Online Smalltalk Books (meta-list)

Squeak By Example (Smalltalk IDE)

Subversion

Subversion Version Control (PDF)

Version Control with Subversion

SQL (implementation agnostic)

Developing Time-Oriented Database Applications in SQL

Use The Index, Luke! (a guide to SQL database performance for developers)

Teradata

Teradata Books

Vim

A Byte of Vim

Vim Recipes

交互式教程网站http://t.cn/aep0mV

很全的 Vim 速查卡:http://t.cn/aBPFPk

Websphere

Getting started with WebSphere (PDF)

二、 TG 推荐了麻省理工学院的一门课程

Structure and Interpretation of computer programs / 计算机程序员结构和解析》,这门课程视频地址是:http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/

三、 Gatekiller 推荐的资源如下:

How to Design Programs

Graphics Programing Black Book

Real World Haskell

Let Over Lambda

Starting Forth

List of Free Online Python Books

List of Free Online Perl Books

Squeak by Example

C# Essentials

List of Free Online Smalltalk Books

Successful Lisp

Introduction to Functional Programming

四、ani625推荐了一些 Linux 相关书籍

The Art of Unix Programming

Advanced Linux Programming by CodeSourcery LLC

Java Application Development on Linux by Carl Albing and Michael Schwarz (PDF)

Advanced Linux Programming

Secure Programming for Linux and Unix

The Linux Development Platform

Secure Programming for Linux and Unix HOWTO

C++ GUI Programming With Qt 3

Linux Kernel Module Programming Guide by Ori Pomerantz

KDE 2.0 Development

GTK+/Gnome Application Development

GNU Autoconf, Automake and Libtool

The Linux Kernel Module Programming Guide

PHP Essentials

JavaScript Essentials

Visual Basic Essentials

上面这4个推荐,是得票数最高的前4位。下面这些得票数不太高的,从中挑选了一些。

The Django Book, GNU Free Document License

Mercurial (Hg) book by Bryan O’Sullivan. (Mercurial 是一个分布式版本控制软件)

37 Signals’ 公司的 “Getting Real” 也提供免费在线阅读。

Clever Algorithms: Nature-Inspired Programming Recipes 》描述了人工智能领域中的 45 个算法。所以这些算法的描述都连贯并完整,确保广大受众可以理解。 这本书也有免费的 PDF 版,也可以在线免费阅读

麻省理工学院关于计算机科学的开源课程:http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/index.htm

《Practical Common Lisp(实用 Common Lisp 编程)》Sergio Acosta 强烈推荐的,特别适合对 Lisp 感兴趣的初学者,虽然这本书的纸质版并不免费,但作者 Peter Seibel 允许免费在线阅读

[原创]EasyUI的treegrid组件动态加载数据问题解决办法

mikel阅读(1222)

最近涉及到treegrid组件的查询,需要根据查询条件动态更新EasyUI的treegrid组件的动态加载查询结果,搜遍了treegrid源码和文档发现treegrid是扩展自datagrid和tree的,不过以往利用datagrid的

reload方法加参数的方式加载查询结果数据,可是treegrid却只执行reload不能加载带参数的查询结果,可能是做了限制,如下代码不能加载查询结果:

<table id='treegrid' class='easyui-treegrid' url='/User/List'></table>

$('#treegrid').treegrid('reload',{'name':'mikel'});

于是又去官方论坛搜索相关问题,发现一个有价值的帖子,茅塞顿开,为什么要指望treegrid组件来异步查询数据,为什么不先异步,然后在加载返回的json数据呢?代码如下:

function loadData()
{
$.post('/User/List',{name:'mikel'},function(data){
  $('#treegrid').treegrid('loadData',data);
},'json');
}

[转载]利用Nginx实现最简单的防盗链

mikel阅读(932)

[转载]利用Nginx实现最简单的防盗链 – kudy – 博客园.

一、文件的防盗链:

location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked www.kudystudio.com kudystudio.com;
if ($invalid_referer) {
rewrite ^/ http://www.kudystudio.com/403.html;
#return 403;
}
}

第一行:gif|jpg|png|swf|flv 表示对gif、jpg、png、swf、flv后缀的文件实行防盗链
第二行: 表示对www.kudystudio.com kudystudio.com这2个来路进行判断
if{}里面内容的意思是,如果来路不是指定来路就跳转到http://www.kudystudio.com/403.html页面,当然直接返回403也是可以的。
二、目录的防盗链:

location /images/ {
alias /data/images/;
valid_referers none blocked server_names *.kudystudio.com kudystudio.com;
if ($invalid_referer) {
return 403;
}
}

下载nginx1.0

[转载]ASP.NET MVC:自定义 Route 让你的 Url 更优雅

mikel阅读(979)

[转载]ASP.NET MVC:自定义 Route 让你的 Url 更优雅 – 鹤冲天 – 博客园.

如今,互联网越来越注重简单优雅的 Url,对比下面两个:

我相信大多数朋友会更喜欢第二种方式:小写,使用负(减)号作为连字符。

本文使用自定义 Route 来达到方式二的效果,只需增加几个类和简单修改下 global.asax 文件。

Route 是双向的

Route 的基本概念我就不多说了,这里重点强调一下 ASP.NET MVC 中 Route 是双向的,这可以从 RouteBase 类的定义可以看出:

1
2
3
4
public abstract class RouteBase{
    public abstract RouteData GetRouteData(HttpContextBase httpContext);
    public abstract VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
}

GetRouteData 用于解析 Url,GetVirtualPath 用于生成 Url。

在开始编写我们的 Route 类之前,我们需要一个用于处理字符串的静态类:

StringElegantHelper 类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
internal static class StringElegantHelper {

    public static readonly char minus = '-';

    public static string Elegant(string s) {
        var builder = new StringBuilder();
        var index = 0;
        foreach (var c in s) {
            if (c >= 'A' && c <= 'Z') {
                if (index > 0) builder.Append(minus);
                builder.Append(char.ToLower(c));
            }
            else if (c == minus) {
                builder.Append(minus);
                builder.Append(minus);
            }
            else
                builder.Append(c);
            index++;
        }
        return builder.ToString();
    }

    public static string DeElegant(string s) {
        var builder = new StringBuilder();
        var iterator = s.GetEnumerator();
        while (iterator.MoveNext()) {
            if (iterator.Current != minus) {
                builder.Append(iterator.Current);
                continue;
            }
            if (!iterator.MoveNext()) {
                builder.Append(minus);
                break;
            }
            if (iterator.Current == minus)
                builder.Append(minus);
            else
                builder.Append(iterator.Current);
        }
        return builder.ToString();
    }
}

StringElegantHelper 中有两个方法 Elegant 和 DeElegant,将分别用在 GetVirtualPath 和 GetRouteData 方法中,用于生成和解析优雅的 Url。

这两方法也可以使用正则表达式来实现,但我认为效率不高,就采用了上面这种最朴实的方式。

有了 StringElegantHelper 类,写出 ElegantRoute 就简单多了:

ElegantRoute 类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class ElegantRoute : Route {

    public static readonly string[] ToElegant =  new [] { "controller", "action" };

    public ElegantRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler)
        : base(url, defaults, constraints, dataTokens, routeHandler) { }

    public override RouteData GetRouteData(HttpContextBase httpContext) {
        var result = base.GetRouteData(httpContext);
        if (result == null) return null;

        foreach (var key in ToElegant)
            HandleItem(result.Values, key, StringElegantHelper.DeElegant);
        return result;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) {
        var elegantValues = new RouteValueDictionary(values);
        foreach (var key in ToElegant)
            HandleItem(elegantValues, key, StringElegantHelper.Elegant);
        return base.GetVirtualPath(requestContext, elegantValues);
    }

    private void HandleItem(RouteValueDictionary dict, string key, Func<string, string> handler) {
        if (!dict.ContainsKey(key)) return;
        //
        var value = dict[key];
        if (!(value is string)) return;
        //
        dict[key] = handler(value as string);
    }
}

注意,上面代码中只对 controller 和 action 的路由值进行了“优雅”处理,其它值并没有,为什么呢?

大家可以考虑以下网址:

~/customers/details/ANTON

全部处理的话会变成:

~/customers/details/a-n-t-o-n

代码其他部分比较简单,不多说了。

最后,还需要几个扩展方法,以方便在 global.asax 文件中使用:

ElegantRouteExtensions 类

1
2
3
4
5
6
7
8
9
10
11
public static class ElegantRouteExtensions {
    public static ElegantRoute MapElegantRoute(this RouteCollection routes, string name, string url, object defaults) {
        var route = new ElegantRoute(url,
            new RouteValueDictionary(defaults),
            new RouteValueDictionary(), //constraints
            new RouteValueDictionary(), //dataTokens
            new MvcRouteHandler());
        routes.Add(name, route);
        return route;
    }
}

我只写出一个,大家可根据需要添加。

使用 ElegantRouter

借助上面的扩展方法,使用就很相当简单了。

global.asax 文件中,把 routes.MapRoute 替换为 routes.MapElegantRoute 即可:

1
2
3
4
5
routes.MapElegantRoute(  // MapRoute
    "Default", 
    "{controller}/{action}/{id}", 
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
);

运行起来验证,点下右上角的 [ Log On ]  链接:

image

ElegantRoute 生成和解析通过。

本文代码未严格测试,如有 bug,请在回复中告知,不胜感激!

源码下载:ElegantRouteDemo.rar (75KB)

在线演示:http://demo.highsoft.cc/products

[转载]C# 邮件发送,可根据需求修改为群发~

mikel阅读(1533)

[转载]C# 邮件发送,可根据需求修改为群发~ – Andrew.Wangxu – 博客园.

– -,

我直接上图 上代码吧。

代码:

using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Text;  
using System.Windows.Forms;  
using System.Net;  
using System.Net.Mail;  
using System.Net.Mime;  
using System.IO;  
  
namespace SendMailExample  
{  
    /// <summary>  
    /// 作者:Andrew  
    /// Blog: http://blog.csdn.net/Andrew_wx  
    /// </summary>
    public partial class FormSendMail : Form  
    {  
        public FormSendMail()  
        {  
            InitializeComponent();  
        }  
  
        private void FormSendMail_Load(object sender, EventArgs e)  
        {  
            txtSmtpServer.Text = "smtp.qq.com";  
            txtSend.Text = "heuandmei@qq.com";  
            txtDisplayName.Text = "Andrew(王旭)";  
            txtPassword.Text = "";//密码  
            txtReceive.Text = "heuandmei@qq.com";  
            txtTitle.Text = "发信测试";  
            txtBody.Text = "This is a test(测试)";  
            rbtnNoSSL.Checked = true;  
        }  
  
        private void btnAddFiles_Click(object sender, EventArgs e)  
        {  
            OpenFileDialog odlg = new OpenFileDialog();  
            odlg.CheckFileExists = true;  
            //只接收有效的文件名  
            odlg.ValidateNames = true;  
            //允许一次选择多个文件作为附件  
            odlg.Multiselect = true;  
            if (odlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)  
            {  
                lstFiles.Items.AddRange(odlg.FileNames);  
            }  
              
        }  
  
        private void btnSend_Click(object sender, EventArgs e)  
        {  
            this.Cursor = Cursors.WaitCursor;  
            MailMessage mail = new MailMessage();  
            mail.From = new MailAddress(  
                txtSend.Text, txtDisplayName.Text, Encoding.UTF8);  
            mail.To.Add(txtReceive.Text);  
            mail.Subject = txtTitle.Text;  
            mail.SubjectEncoding = Encoding.Default;  
            mail.Body = txtBody.Text;  
            mail.BodyEncoding = Encoding.Default;  
            mail.IsBodyHtml = false;  
            mail.Priority = MailPriority.Normal;  
            //添加附件  
            Attachment attachment = null;  
            if (lstFiles.Items.Count > 0)  
            {  
                for (int i = 0; i < lstFiles.Items.Count; i++)  
                {  
                    string pathFileName = lstFiles.Items[i].ToString();  
                    string extName = Path.GetExtension(pathFileName).ToLower();  
                    //判断附件类型  
                    if (extName == ".rar" || extName == ".zip")  
                    {  
                        attachment = new Attachment(pathFileName, MediaTypeNames.Application.Zip);  
                    }  
                    else  
                    {  
                        attachment = new Attachment(pathFileName, MediaTypeNames.Application.Octet);  
                    }  
                    ContentDisposition cd = attachment.ContentDisposition;  
                    cd.CreationDate = File.GetCreationTime(pathFileName);  
                    cd.ModificationDate = File.GetLastWriteTime(pathFileName);  
                    cd.ReadDate = File.GetLastAccessTime(pathFileName);  
                    mail.Attachments.Add(attachment);  
  
                }  
            }  
            SmtpClient client = new SmtpClient();  
            client.Host = txtSmtpServer.Text;  
            client.Port = 25;  
            //是否使用安全套接字层加密连接  
            client.EnableSsl = rbtnUseSSL.Checked;  
            //不使用默认凭证,注意此句必须放在 client.Credentials 的上面  
            client.UseDefaultCredentials = false;  
            client.Credentials = new NetworkCredential(txtSend.Text, txtPassword.Text);  
            //邮件通过网络直接发送到服务器  
            client.DeliveryMethod = SmtpDeliveryMethod.Network;  
            try  
            {  
                client.Send(mail);  
                MessageBox.Show("发送成功");  
            }  
            catch (SmtpException ex)  
            {  
                MessageBox.Show("发送失败:" + ex.Message);  
            }  
            catch (Exception ex)  
            {  
                MessageBox.Show("发送失败:" + ex.Message);  
            }  
            finally  
            {  
                mail.Dispose();  
                client = null;  
                this.Cursor = Cursors.Default;  
            }  
        }  
    }  
}

以上是完整代码。

项目包下载地址:http://files.cnblogs.com/andrew-blog/SendMailExample.rar

[转载]ERP系统管理员的工具箱 推荐几款优秀的数据比较同步工具 Data Compare and Sync tool

mikel阅读(987)

[转载]ERP系统管理员的工具箱 推荐几款优秀的数据比较同步工具 Data Compare and Sync tool – James Li – 博客园.

最近一直在帮忙客户找程序方面的问题。当确定不是程序上的问题后,痛苦的过程就开始了: 帮助客户修复计算错误的数据,也叫Data Fix。我们的ERP系统有1000多个表,有100个基础数据表,比如物料表,物料清单,工作单,销售单,采购单,这里包含表头(Header)和表明 细(Detail),再加上100多个数据关联表,比如工作单与销售单的关联,工作单与物料进出,物料进出与仓库日记帐,仓库日记帐进而产生传票 (voucher),成本(cost),这样加起来,又有100个多表。当发现程序有计算错误后,通常会修复程序,再帮助用户修复计算错误的数据。有时候 程序修改好后,由于没有合并到客户的版本中,导致客户的数据计算错误,日记帐与总帐对不上,这时,只好一行一行的来修复数据了,修复错误的数据。

为了追踪到是哪一行的程序计算出了问题,通常是在测试系统中做一笔新的业务,让它产生一连串的数据,这肯定是对的,然后把它与客户的有问题的系统对比,看看是哪几个field出了问题,修复这几个field的关联问题。

一开始依靠自己对系统的熟悉程度来对做,虽然也能解决问题,但非常耗费时间,写大量的SQL语句。折腾过几次之后,想到这一类问题经常会碰到,于是搜索了一下,找到下面的几个工具,以帮助解决这类问题。

dbForge Data Compare

clip_image002

Data Compare 是比较两个数据库的数据是否相同。在有问题的客户系统中做一笔业务,同时在没有问题的系统中也做一笔同样的业务,再用这个工具比较一下,两者数据的不同之处,问题很快就可以定位到field,修复它即可。

SQL Data Compare

clip_image002[5]

这 一款工具由Red Gate公司出品,我们熟悉的.NET Reflector就是这个公司推出的,它的SQLToolbet也是非常有名,SQL Data Compare是SQLToolbet系列工具中的一种。Red Gate公司出品的这款Data Compare 工具稳定,好用。它还有一个很有用的feature是,可以比较备份集中的数据。也就是我们把客户数据备份之后,拷贝回来,可以直接在这里比较,而不用还 原到SQL Server中。另外,如上图所示,它有一个Synchronization Wizard,可以根据两个正在比较的数据库的差别,产生同步的脚本,把这个脚本放到另一个数据库中运行一下,这两个数据库就是一模一样的了。这个特性, 我常常用于分析Kingdee,Microsoft Dynamic AX的业务操作。举例说明,我要知道金蝶ERP的采购单过帐到底做了那些工具,除了打开SQL Server Profiler跟踪它的SQL之外,再打开这个工具,比较一下采购单过帐前与过帐后数据库中数据的差异,就可以知道它做了哪些数据操作,依据它的表名的 含义(表的含义与用途是公开的),进而推论到它的程序实现。依照这个工具,更新和晚上ERP业务系统。

SQL Delta 4

clip_image002[7]

这一款工具也好用,方便。也提供了Sync同步工具。此外,它还可以产生报表,以显示两个数据库的差异。如上图所示,在下方,它以Tab的方式显示了所有的差异,很直观。

Visual Studio Database Edition

微软的Visual Studio 2010也触及到了这个领域,它推出了两款工具Schema Compare和Data Compare。

image

在 微软的上一个版本Visual Studio 2008中,它Database Edition提供了SQL脚本解析API,有了SQL语法的解析能力,我以此做成了代码生成工具。代码生成不仅仅依赖于数据库,我用反射技术解析程序集 接口也可以做代码生成,用SQL语句解析生成ORM接口及其实现也做成了代码生成,这两个功能都和数据库没有关系。

在这里,也提供了同 步工具。工具栏中的Write Updates,生成同步脚本。微软是这类工具的后来者,肯定会吸收市场上现有工具的优点,该有的功能,它都提供了。而且就集成在我们每天要用的 Visual Studio中,既然是Visual Studio的一部分,微软的目标应该是我们程序员了,而不是ERP管理员,数据库管理员。如果怕麻烦,ERP程序管理员,应该不会考虑用微软的这款数据 比较同布工具。