LINQ to FQL是一个开源项目。源码,编译文件以及示例都可以从CodePlex上找到。这个类库扩展于Facebook Developer Toolkit.
这个类库允许开发者使用Linq(.Net语言集成查询)查询Facebook替代基于字符串的FQL查询.使用这个类库的主要好处是:
例如:下面的示例代码检索的姓名和你的朋友的所有图片。
var db = new FacebookDataContext();
var friendIDs = from friend in db.friend_info where friend.uid1 ==
db.uid select friend.uid2;
var friendDetails = from user in db.user where friendIDs.Contains(user.uid)
select new { Name = user.name, Picture = user.pic_small };
虽然Linq的核心是可扩展的,但Linq To Sql(以前称为DLinq)却不行.它的执行时内部而且仅支持Sql Server.为了本身支持FQL,它必需从头模仿Linq To Sql核心,如下:
FqlDataContext是一个数据源,支持FQL和FqlTable实例组成。 FqlTable代表了模型表,并作为目标提供LINQ查询。 FqlDataQuery代表LINQ查询是通过一个FqlTable执行。FqlProvider管理的改造和查询的执行。 FqlQueryBuilder LINQ表达式转换为FQL字符串。FacebookDataContext继承自FqlDataContext,并公开Facebook的开发工具包的表模型。
一个LINQ to FQL查询流看起来像这样:
FqlQueryResultEnumerator.GetEnumerator)
Linq To FQL的转换通过FqlQueryBuilder类实现.这个类接受一个表达式树,那是一个System.Linq.Expressions.Expression实例,然后迭代和递归及其子表达式.在迭代期间,每个子表达式被确定,并将它的表达式数据和当前构造状态转换为FQL文本,例如:
若干类和接口被用于和LINQ集成:
IEnumerable,IEnumerable,IEnumerator,IEnumerator <T>被用于返回物理的iteratable结果。IQueryable的,IQueryable的<T>的用于创建类,有更多的对LINQ的是它采用的查询控制。IQueryProvider用于重写和执行查询。主类,作为处理该库LINQ查询服务的目标是FqlTable <T>类的同时实现了IQueryable的和IQueryProvider接口。
public class FqlTable<T> : IQueryable, IQueryable<T>, IQueryProvider
{
//IQueryable
public IQueryProvider Provider
{
get { return this; }
}
//IQueryProvider
public IQueryable<TResult> CreateQuery<TResult>(Expression expression)
{
return new FqlDataQuery<TResult>(this.context, expression, typeof(T));
}
}
此示例可上网,只需点击运行按钮来运行该示例,或源文件的任何点击查看或修改它们。
为了在本地运行示例,请按照下列步骤:
您可以运行该应用程序,注意,它将使用一个预定义的通用Facebook应用(对CodeRun提供),将Facebook的重定向到本地样本。为了使用自己的应用程序,继续以下步骤:
<appSettings>
<add key="Facebook.Linq.ApplicationID" value="xxxxxxxx" />
<add key="Facebook.Linq.APIKey" value="xxxxxxxxxxxxxxxxxxxxxx" />
<add key="Facebook.Linq.Secret" value="xxxxxxxxxxxxxxxxxxxxxx" />
</appSettings>
运行按一下这里的Visual Studio或运行应用程序。
主要入口点使用LINQ查询是FacebookDataContext类。这个类应该包含Facebook的所有表,每个表可查询使用LINQ。要使用它- FacebookDataContext创建一个新的实例,并使用它的任何表属性LINQ的。
var db = new FacebookDataContext();
var myUser = db.user.Where(t => t.uid==db.uid).FirstOrDefault();
它也可以指定确切的连接到Facebook要使用,使用facebook.API类(在Facebook的开发工具包组装中)。
var api = new API { ApplicationKey = "MyAppKey",
AuthToken = "MyAuthToken", SessionKey = "MySessionKey", Secret = "MySecret" };
var db = new FacebookDataContext(api);
有两种类型的语法使用LINQ,一个被称为LINQ查询语法,另一种是LINQ的方法的语法。 LINQ查询语法是一个新的执行情况和当地的C#3.0语言的一部分。这是不可扩展的,因此它有一些局限性。好消息是,这两种类型的语法可以混合在同一查询并获得相同的结果。
var db = new FacebookDataContext();
//LINQ Query Syntax
var friendsIDs = from friend in db.friend_info where friend.uid1 ==
db.uid select friend.uid2;
//LINQ Method Syntax (the same query)
var friendsIDs2 = db.friend_info.Where(t => t.uid1 == db.uid).Select(t => t.uid2);
FQL支持只有在每一个表查询中使用,这意味着表联接不支持。上档方面,FQL允许多个表使用嵌套查询和使用也是如此的LINQ to FQL。今后,该库应赔偿转化LINQ表达式,使用JOIN子句的嵌套或多重FQL查询这个缺点。
var db = new FacebookDataContext();
var friendIDs = from friend in db.friend_info where friend.uid1 ==
db.uid select friend.uid2;
var friendDetails = from user in db.user where friendIDs.Contains(user.uid) select user;
//Or in a single line
var friendDetails2 = from user in db.user where
(from friend in db.friend_info where friend.uid1 ==
db.uid select friend.uid2).Contains(user.uid) select user;
使用LINQ检索特定的属性是通过使用SELECT子句,这是一个在查询优化的重要组成部分,因为它最大限度地从Facebook返回的数据。选择条款通常要求您有其他对象,你可以把你选择的数据,但是不用担心,匿名类型使得工作非常简单。匿名类型允许您定义的隐式的只读属性的某些设置一个新的类。在这个例子中,一个匿名类型将创建具有两个属性-名字和照片,都将是字符串类型。
var db = new FacebookDataContext();
var friendIDs = from friend in db.friend_info where friend.uid1 ==
db.uid select friend.uid2;
var friendDetails = from user in db.user where friendIDs.Contains(user.uid)
select new { Name = user.name, Picture = user.pic_small };
进行排序使用的OrderBy条(使用查询语法)或的OrderBy方法(使用方法的语法)。分页执行使用跳过和采取的方法,请注意传呼没有一个LINQ查询语法的选择。寻呼也是对查询优化的重要组成部分,因为它限制了将来自Facebook返回的行数。
var db = new FacebookDataContext();
var friendIDs = from friend in db.friend_info where friend.uid1 ==
db.uid select friend.uid2;
var friendDetails = (from user in db.user where friendIDs.Contains(user.uid)
orderby user.name select new { Name = user.name,
Picture = user.pic_small }).Skip(4).Take(5);
该facebook.Web命名空间包含旨在帮助Facebook的集成了一些有用的类。不过,他们不是至关重要的LINQ to FQL基础设施。例如,当您使用FacebookDataContext空构造,上下文facebook.API对象将被使用。这方面是可通过FacebookContext.Current财产或FacebookContext.Get(HttpContext的)方法,并包含所有有关Facebook的背景资料,如当前登录的用户和应用程序信息。默认的应用程序将由FacebookDataContext类使用的定义在你的web.config文件。
<appSettings>
<add key="Facebook.Linq.ApplicationID" value="xxxxxxxx" />
<add key="Facebook.Linq.APIKey" value="xxxxxxxxxxxxxxxxxxxxxx" />
<add key="Facebook.Linq.Secret" value="xxxxxxxxxxxxxxxxxxxxxx" />
</appSettings>
对于一个FacebookContext的全力支持,你也应登记在你的web.config文件FacebookCallback处理。在FacebookCallback处理自动化和回调重定向从Facebook,但它也可以自动登录过程。
<system.web>
<httpHandlers>
<add verb="*" path="FacebookCallback.ashx" type="Facebook.Web.FacebookCallback,
Facebook.Linq, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null" validate="false"/>
</httpHandlers>
</system.web>
使用这种技术,更容易验证用户登录,如果他不是,他将被重定向到Facebook的登录页面。
if (FacebookContext.Current.TryAuthenticating(true))
{
var db = new FacebookDataContext(); //in here the FacebookDataContext
// object will use the currently authenticated user connection info.
}
虽然FqlDataContext是一个通用的实施,旨在与任何模型,FacebookDataContext类派生自它,实现了一个具体的Facebook的模式。这使您可以灵活地创建自己的Facebook的模式,它们映射到FQL使用自定义属性。该库实际上是支持相同的自定义为本地LINQ的属性SQL实现,这些TableAttribute和ColumnAttribute。例如,考虑这一习俗,更方便使用Facebook的模式:
[Table(Name="album")]
public class Album
{
[Column(Name="aid", IsPrimaryKey=true)]
public long ID { get; set; }
[Column(Name="cover_pid")]
public long CoverPictureID {get;set;}
}
public class FacebookFriendlyDataContext : FqlDataContext
{
public FqlTable<Album> Albums
{
get
{
return GetTable<Album>();
}
}
}
LINQ to FQL 是一个有力的工具,应小心使用。重要的是要记住,您的应用程序无法与本地数据库,而是一个远程服务。任何数据,您的申请获得通过这条管道穿过作为一个XML消息互联网。因此,它是非常重要的尝试并获得唯一的数据应用程序的实际需要。最常见的方式这样做的: