Code4Fun: LINQ2Douban Demo Code
LINQ2Douban是基于LINQToolKit的douban网的api的全功能调用框架。通过LINQ2Douban,你可以用LINQ-Style的方式对douban的数据进行CRUD操作。本文示例了如何使用LINQ2Douban来实现对Douban API的调用。
LINQToolKit是基于.Net的Web API调用框架。通过定义的XML Mapping,可以实现XML和单个实体对象和关系之间的映射,并可以在运行时对需要访问的属性进行延迟加载。LINQToolKit封装了LINQ style的查询和数据处理方式,基于LINQToolKit你可以用from/where/select来直接进行查询,这些关键字的语义可以通过定义的QueryRule来生成相应的查询uri(用于invoke web api),并且可在上面进行任何Enumerable和Querable允许的的数据操作。
LINQToolKit可以通过扩展支持任何规范的web api,自带了Google Data API的支持
LINQ2Douban是基于LINQToolKit的douban网的api的全功能调用框架。通过LINQ2Douban,你可以用LINQ-Style的方式对douban的数据进行CRUD操作。
声明:LINQ2Douban不是官方框架,K.K只是douban的忠实用户
相关信息
douban api讨论组:http://www.douban.com/group/dbapi/
google data protocol :http://code.google.com/apis/gdata/docs/2.0/reference.html
你可以通过google code获取LINQToolKit和LINQ2Douban的所有代码和Example
http://code.google.com/p/linqtodouban/
demo code源码下载:
http://linqtodouban.googlecode.com/files/LINQ2Douban%20Demo.rar (for vs2010 beta2 solution)
https://files.cnblogs.com/chwkai/DoubanDemo.rar (for vs2008 solution)
所有疑问和错误请和K.K邮件联系chwkai@gmail.com
关于LINQToolKit稍后会有文档介绍
准备工作
在运行Demo Code之前,请先修改context.config文件中的access token,如何获取access token请访问douban api组
<request type="LINQToolKit.Douban.DoubanRequest, LINQToolKit.Douban"> <!-- <apiKey></apiKey> <apiKeySecret></apiKeySecret> <accessToken></accessToken> <accessTokenSecret></accessTokenSecret> --> </request>
Demo Code
/// <summary> /// Demos for LINQToolKit.Douban /// </summary> /// <remarks> /// This framework is under the GNU licence and Creative Commons 3.0. /// You can also get a copy of the source code from google code /// <see cref="http://linqtodouban.googlecode.com/svn/trunk/"/>. /// For more information and further support, please contace with kevin (chwkai@gmail.com) /// </remarks> class Program { static void Main(string[] args) { var context = new DoubanContext(); // 用于输出查询的url context.Log = Console.Out; context.Me.Title.Dump(); // 回复广播(需要授权) // context.CommentMiniBlog("miniBlogId", "content"); // 参与指定活动(需要授权) //context.ParticipateEvent("eventId"); // 对活动感兴趣(需要授权) // context.FollowEvent("eventId"); // 退出活动(需要授权) // context.QuitEvent("eventId"); // 删除活动(需要授权) // context.DeleteEvent("eventId", "reason"); // 回复推荐 // context.CommentOnReco("recommendId", "content"); // 删除推荐的回复 // context.DeleteCommentOnReco("recommendId", commentId); // 批量设置豆油已读 // context.SetMailsRead(string[] mails); // 批量删除豆油 // context.DeleteMails(string[] mails); // 验证access token是否可用 // context.IsTokenAvailabe(token); // 注销token // context.CancelToken(token); } /// <summary> /// 获取用户豆油(需要授权,只能看Me的) /// </summary> /// <param name="context"></param> private static void GetUserMails(DoubanContext context) { // 未读邮件 // context.Me.UnReadMails; // 已发邮件 // context.Me.OutboxMails; foreach (var item in context.Me.Mails) { item.Title.Dump(); } } /// <summary> /// 获取用户所有推荐 /// </summary> /// <param name="context"></param> private static void GetUserRecos(DoubanContext context) { foreach (var item in context.Me.Recommends) { item.Title.Dump(); //获取推荐回复 foreach (var cc in item.Comments) { cc.Title.Dump(); } } } /// <summary> /// 获取指定城市id的活动 /// </summary> /// <param name="context"></param> private static void GetLocationEvents(DoubanContext context) { var events = (from e in context.Events where e.Location.ID == "beijing" select e).Take(10); foreach (var item in events) { item.Title.Dump(); } } /// <summary> /// 获取指定用户所有活动 /// </summary> /// <param name="context"></param> private static void GetUserEvents(DoubanContext context) { // 用户参与的活动 //context.Me.ParticipateEvents // 用户感兴趣的活动 //context.Me.WishEvents // 用户发起的活动 //context.Me.InitiateEvents foreach (var item in context.Me.Events) { item.Title.Dump(); } } /// <summary> /// 获取用户所有日记(延迟加载) /// </summary> /// <param name="context"></param> private static void GetUserNotes(DoubanContext context) { foreach (var item in context.Me.Notes) { item.Title.Dump(); } } /// <summary> /// 获取指定用户广播 /// </summary> /// <param name="context"></param> private static void GetUserMiniBlogs(DoubanContext context) { var user = context.Peoples.GetByID("ahbei"); foreach (var item in user.MiniBlogs) { item.Title.Dump(); // 获取广播回复 foreach (var c in item.Comments) { c.Title.Dump(); } } } /// <summary> /// 获取友邻广播 /// </summary> /// <param name="context"></param> private static void GetContactMiniBlogs(DoubanContext context) { foreach (var item in context.Me.ContactMiniBlogs) { item.Title.Dump(); } } /// <summary> /// 获取指定用户收藏 /// </summary> /// <remarks> /// 此处以Me为例,也可以换成查询得来的People。当访问这些属性时,会自动加载数据 /// </remarks> /// <param name="context"></param> private static void GetPeopleCollections(DoubanContext context) { // 获取音乐收藏 // context.Me.Musics // 获取电影收藏 // context.Me.Movies // 获取书籍搜藏 foreach (var item in context.Me.Books) { item.Title.Dump(); } } /// <summary> /// 删除指定id的评论 /// </summary> /// <param name="context"></param> private static void DeleteReview(DoubanContext context) { // 代码中的id更换为有效id var review = context.Reviews.GetByID("2902263"); context.Reviews.Delete(review.ID); } /// <summary> /// 更新指定的id的评论 /// </summary> /// <param name="context"></param> private static void UpdateReview(DoubanContext context) { // 代码中的id更换为有效id var review = context.Reviews.GetByID("2902263"); review.Content = "Udpat content test for linq2douban"; context.Reviews.Update(review.ID, review); } /// <summary> /// 发表评论 /// </summary> /// <remarks> /// 发表短的Content内容,douban api会报失败 /// </remarks> /// <param name="context"></param> private static void AddReview(DoubanContext context) { var review = new Review { // 如果Subject是从API读回来的,Source属性会自动赋值 Subject = new Movie { Source = "http://api.douban.com/movie/subject/1424406" }, Rating = new Rating { Value = 4 }, Content = "this is the test for linq2doubanddddddddddddddddddddddddddddddddddddddddd", Title = "this is the test for linq2douban" }; context.Reviews.Insert(review); } /// <summary> /// 获取指定书籍/电影/音乐的评论 /// </summary> /// <param name="context"></param> private static void GetSubjectReviews(DoubanContext context) { var movie = context.Movies.GetByID("1424406"); movie.Reviews.Count().Dump(); } /// <summary> /// 获取用户所有评论 /// </summary> /// <remarks> /// 此例用me做示例,获取指定的用户的评论,访问People.Reviews属性即可,框架会延迟加载 /// </remarks> /// <param name="context"></param> private static void GetReviews(DoubanContext context) { foreach (var item in context.Me.Reviews) { item.Title.Dump(); } } /// <summary> /// 示例复合查询(关键字,startindex,maxtresult) /// </summary> /// <remarks> /// douban的startindex, maxresult的含义与常识理解不通, /// douban的maxresult表示取回数据的最大下标,所以Take(20).Skip(10)返回下标为10-20共11条数据 /// </remarks> /// <param name="context"></param> private static void GetBooks(DoubanContext context) { var query = context.Books.Has("新东方").Take(20).Skip(10); foreach (var item in query) { item.Title.Dump(); } } /// <summary> /// 用多个条件查询书籍(电影、音乐等,查询同此例) /// </summary> /// <remarks> /// LINQToolKit会根据queries.config里定义的query rules转换成相应的url进行查询, /// 你可尝试用不同关键字匹配,如果有问题请发chwkai@gmail.com /// </remarks> /// <param name="context"></param> private static void GetBooksByQuery(DoubanContext context) { var query = from b in context.Books where b.LongIsbn == "9787543639133" || b.ID == "2023013" select b; foreach (var item in query) { item.Title.Dump(); } } /// <summary> /// 获取指定ID的书籍 /// </summary> /// <remarks> /// 获取指定ID的douban信息与此例相同 /// </remarks> /// <param name="context"></param> private static void GetBookByID(DoubanContext context) { var query = from b in context.Books where b.ID == "2023013" select b; query.Single().Dump(); } /// <summary> /// 获取用户关注的人(延迟加载) /// </summary> /// <param name="context"></param> private static void GetContacts(DoubanContext context) { // context.Me.Contacts 获取当前用户关注的人 var query = from p in context.Peoples where p.ID == "chwkai" select p; // People.Contacts 当需要访问时会延迟加载 query.Single().Contacts.Count().Dump(); } /// <summary> /// 获取用户朋友(延迟加载) /// </summary> /// <param name="context"></param> private static void GetFriends(DoubanContext context) { // context.Me.Friends 获取当前用户的朋友 var query = from p in context.Peoples where p.ID == "chwkai" select p; // People.Friends 当需要访问时会延迟加载 query.Single().Friends.Count().Dump(); } /// <summary> /// 关键字搜索用户 /// </summary> /// <remarks> /// 不是ID的相等比较条件都会转换为关键字查询 /// </remarks> /// <param name="context"></param> private static void GetUserByKey2(DoubanContext context) { var query = from p in context.Peoples where p.Title == "net" select p; query.Count().Dump(); } /// <summary> /// 关键字搜索用户 /// </summary> /// <param name="context"></param> private static void GetUserByKey(DoubanContext context) { var query = context.Peoples.Has("net"); query.Count().Dump(); } /// <summary> /// 获取当前用户(需要授权) /// </summary> /// <param name="context"></param> private static void GetCurrentUser(DoubanContext context) { context.Me.Content.Dump(); } /// <summary> /// 获取单个用户信息 /// </summary> /// <param name="context"></param> private static void GetOneUserLinqStyle(DoubanContext context) { var user = from u in context.Peoples where u.ID == "chwkai" select u; user.Single().Content.Dump(); } /// <summary> /// 获取单个用户信息 /// </summary> /// <param name="context"></param> private static void GetOneUser(DoubanContext context) { var user = context.Peoples.GetByID("chwkai"); user.Content.Dump(); }
All the posts in this blog are provided "AS IS" with no warranties, and confer no rights. Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution 2.5 China Mainland License.