如何在墙内反代 Gravatar 显示博客头像

生命不息,折腾不止

Gravatar 即全球通用头像 (Globally Recognized Avatar) 服务,用户只要在上面上传了自己的头像,那么在所有支持的网站上发帖时,只要提供与这个头像关联的 Email,就可以显示出自己的 Gravatar 头像。可以说是「一次上传,全网通用」~~

可惜国内的网络环境实在一言难尽,Gravatar 常年都处于无法访问的状态,所以本站一直都是用 v2ex 提供的 CDN 镜像,然而,就在前两周,v2ex 也被墙了,emm…. 因为不想再白嫖其他的国内镜像,因此开始考虑自己动手搭建。这个事情其实挺简单的,网上随便搜索一下就有答案,只要有一台墙外的 VPS,用 nginx 给 Gravatar 做个反向代理就好。

但是,如果你的主机在墙内呢,怎么办?

阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part IX: Removing redundant subqueries

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

现在写一篇新的文章的时间变得越来越长,似乎已经成了一个趋势了。要怪就怪电视编剧罢工吧,嗯。

Cleaning up the Mess

我之前说过要把我们的查询翻译器不断累积下来的不必要的嵌套select表达式给清理掉。对于人类的大脑来说,简化一条SQL是一件很简单的事情。但是,对于计算机程序而言,保留这些无用的嵌套查询却更加容易,毕竟它们的语义是一样的。再者,我们希望少写一点代码的心情也无可厚非。

我们很容易就能从一条带有where子句的简单的查询中看出问题所在。

1
2
3
from c in db.Customers
where c.Country == "UK"
select c;
阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part VIII: OrderBy

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

距离上篇文章,又已经过了几个星期。我感觉大家可能已经迫不及待想要看到下篇文章了。你们的提供程序本来应该已经完成,可以拿到外面去惊艳众人,但是现在却放在角落里吃灰。

Implementing OrderBy

今天的话题是翻译order-by子句。幸运的是,进行排序操作的方式只有一种,那就是LINQ的排序操作符。但坏消息是,有四种不同的操作符。

使用查询的语法来写一条排序的查询是很简单的,只需一个子句就好。

1
2
3
var query = from c in db.Customers
orderby c.Country, c.City
select c;

但是,将上面的查询转换为方法调用的形式的话,所涉及到的就不止是一个LINQ操作符了。

阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part VII: Join and SelectMany

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

从上篇文章到现在,已经有好几个星期没有更新了。希望在这段时间里面你们也有用自己的时间来探索如何构建自己的提供程序。我也一直在关注别人的各种各样的“LINQ to XXX”的项目,感觉都很不错。今天我将向你们介绍如何在我的提供程序中添加连接查询的功能,比起只支持select和where来,支持join将能提供更多有趣的用法。

Implementing Join

在LINQ中有许多种不同的连接查询的写法。在C♯或者VB中,如果写了多个from子句,将会产生笛卡尔积的结果,但如果把一个子句的键和另一个子句的键匹配起来,所得到的就是一个连接查询。

1
2
3
4
var query = from c in db.Customers
from o in db.Orders
where c.CustomerID == o.CustomerID
select new { c.ContactName, o.OrderDate };
阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part VI: Nested queries

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

你又以为这个系列已经完成,所以我已经转移到其他阵地上去了吗?因为Select操作工作得非常好,所以你以为前面所讲的就是你构建自己的IQueryable提供程序所需要了解的所有内容了吗?哈!还有很多需要学习的呢,而且,Select操作还是有些漏洞。

Finishing Select

有漏洞?怎么可能?我把你当成从来不会出错的微软大神,但是你却说你给我的是劣质的代码?我把已经把代码复制粘贴到产品里,老板已经说了下周一就启动!你怎么能这么做?(喘气)

放心啦,不是什么严重的漏洞,只是一点小小的缺陷而已。

回想一下,在上篇文章中,我建了四种表达式节点,Table,Column,Select和Projection,它们工作十分良好,不是吗?有漏洞的地方是我没有考虑到所有可以写查询表达式的地方。我考虑到的只是最明显的Projection节点出现在查询表达式树顶的情况。毕竟,因为我只支持SelectWhere,所以最后一个操作必定是这两者之一。我的代码就是这样假设的。

这不是问题所在。

问题是Projection节点也有可能出现在选择器表达式里面,例如,看下面的查询。

1
2
3
4
5
6
7
var query = from c in db.Customers
select new {
Name = c.ContactName,
Orders = from o in db.Orders
where o.CustomerID == c.CustomerID
select o
};
阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part V: Improved Column binding

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

在前面四篇文章里面,我构建了一个LINQ IQueryable提供程序,它可将Queryable.WhereQueryable.Select两个标准查询操作符翻译成SQL,并通过ADO送到数据库中去执行。虽然已经做得很不错,但是这个提供程序还是有一些漏洞,而且我还没有提到其他的查询操作,比如OrderBy和Join等等。如果认为用户写出的查询都像我的demo一样这么理想化的话,你可能就会掉进大坑里去。

阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part IV: Select

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

我是个完美主义者,我做了一个仅仅可以将Where方法翻译为SQL的LINQ提供程序,它可以执行查询并且将结果转换为对象,但我觉得还不够完美,相信你们也这么认为。你们也许想知道从一个简单的示例程序演变成一个成熟的ORM系统的所有细节。但是我并不会做到这个程度,即便如此,我还是觉得,我可以通过介绍如何实现Select操作来覆盖到一些通用的知识点,以方便你编写自己的提供程序。

阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part III: Local variable references

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

第三部分?难道上篇文章还没有讲完吗?我不是做了一个可以翻译和执行SQL命令并且返回一个对象序列的提供程序了吗?

确实如此,但是也仅仅如此而已。我写的那个提供程序的功能实在太弱,它只支持一种查询操作符与少量比较运算符。然而,真正的查询提供程序必须要提供更多的查询操作与更复杂的交互方式。我的查询提供程序甚至还不支持将数据投影为其他形式。

Translating Local Variable References

你知道当查询里面引用了局部变量的时候会发生什么吗?不知道?

1
2
string city = "London";
var query = db.Customers.Where(c => c.City == city);

去试试翻译上面这句查询的时候会出现什么情况吧,我等着你的结果。

阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part II: Where and reusable Expression tree visitor

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

在上篇文章中,我们已经打好了基础,定义了可重用的IQueryableIQueryProvider,它们分别是Query<T>类和QueryProvider类,现在我们来构建一个真正有用的提供程序。我之前说过,一个查询提供程序所做的事就是执行一些“代码”,这些“代码”使用表达式树而不是真正的IL语言来定义。当然,这并不一定是传统意义上的执行。比如说,LINQ to SQL就是将查询表达式翻译为SQL然后送到服务器中去执行的。

我下面给出的示例与LINQ to SQL有点类似,都是针对一个DAO provider对查询进行翻译和执行。但是,我要做个免责声明,在任何意义上,我给出的示例都不是一个完整的提供程序。我只会翻译Where操作,并且只支持在谓词中使用一个字段引用和一些简单的运算符,除此之外没有任何复杂的东西。以后我可能会扩展这个提供程序,但现在仅用于说明的目的。所以不要以为复制粘贴就能得到高质量的代码。

这个提供程序主要做两件事:

  1. 将查询翻译为SQL命令
  2. 将执行命令得到的结果转换为对象
阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part I: Reusable IQueryable base classes

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

这段时间我一直打算写一个系列的文章来介绍如何使用IQueryable构建LINQ提供程序。也一直有人通过微软内部邮件、论坛提问或者直接给我发邮件的方式来给我这方面的建议。当然,通常我都会回复“我正在做一个详尽的Sample来给你们展示这一切”,告诉他们很快所有内容都会发布。但是,相比仅仅发布一个完整的Sample,我觉得一步一步循序渐进地阐述才是一个明智的选择,这样我才能深挖里面的所有细节,而不是仅仅把东西扔给你们,让你们自生自灭。

我要说的第一件事是,在Beta 2版本里面,IQueryable不再只是一个接口,它被分成了两个:IQueryableIQueryProvider。在实现这两个接口之前,我们先过一遍它们的内容。
使用Visual Studio的“go to definition”功能,你可以看到下面的代码

阅读全文 »