转载:http://www.cnblogs.com/chwkai/archive/2009/12/31/1636873.html
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
所有疑问和错误请和K.K邮件联系chwkai@gmail.com
关于LINQToolKit稍后会有文档介绍
在运行Demo Code之前,请先修改context.config文件中的access token,如何获取access token请访问douban api组
1 |
<request type= "LINQToolKit.Douban.DoubanRequest, LINQToolKit.Douban" > |
2 |
<!-- |
3 |
<apiKey></apiKey> |
4 |
<apiKeySecret></apiKeySecret> |
5 |
<accessToken></accessToken> |
6 |
<accessTokenSecret></accessTokenSecret> |
7 |
--> |
8 |
</request> |
1 |
|
1 |
|
Demo Code:
001 |
/// <summary> |
002 |
/// Demos for LINQToolKit.Douban |
003 |
/// </summary> |
004 |
/// <remarks> |
005 |
/// This framework is under the GNU licence and Creative Commons 3.0. |
006 |
/// You can also get a copy of the source code from google code |
007 |
/// <see cref="http://linqtodouban.googlecode.com/svn/trunk/"/>. |
008 |
/// For more information and further support, please contace with kevin (chwkai@gmail.com) |
009 |
/// </remarks> |
010 |
class Program |
011 |
{ |
012 |
static void Main( string [] args) |
013 |
{ |
014 |
var context = new DoubanContext(); |
015 |
// 用于输出查询的url |
016 |
context.Log = Console.Out; |
017 |
context.Me.Title.Dump(); |
018 |
019 |
// 回复广播(需要授权) |
020 |
// context.CommentMiniBlog("miniBlogId", "content"); |
021 |
// 参与指定活动(需要授权) |
022 |
//context.ParticipateEvent("eventId"); |
023 |
// 对活动感兴趣(需要授权) |
024 |
// context.FollowEvent("eventId"); |
025 |
// 退出活动(需要授权) |
026 |
// context.QuitEvent("eventId"); |
027 |
// 删除活动(需要授权) |
028 |
// context.DeleteEvent("eventId", "reason"); |
029 |
// 回复推荐 |
030 |
// context.CommentOnReco("recommendId", "content"); |
031 |
// 删除推荐的回复 |
032 |
// context.DeleteCommentOnReco("recommendId", commentId); |
033 |
// 批量设置豆油已读 |
034 |
// context.SetMailsRead(string[] mails); |
035 |
// 批量删除豆油 |
036 |
// context.DeleteMails(string[] mails); |
037 |
// 验证access token是否可用 |
038 |
// context.IsTokenAvailabe(token); |
039 |
// 注销token |
040 |
// context.CancelToken(token); |
041 |
} |
042 |
043 |
/// <summary> |
044 |
/// 获取用户豆油(需要授权,只能看Me的) |
045 |
/// </summary> |
046 |
/// <param name="context"></param> |
047 |
private static void GetUserMails(DoubanContext context) |
048 |
{ |
049 |
// 未读邮件 |
050 |
// context.Me.UnReadMails; |
051 |
// 已发邮件 |
052 |
// context.Me.OutboxMails; |
053 |
foreach (var item in context.Me.Mails) |
054 |
{ |
055 |
item.Title.Dump(); |
056 |
} |
057 |
} |
058 |
059 |
/// <summary> |
060 |
/// 获取用户所有推荐 |
061 |
/// </summary> |
062 |
/// <param name="context"></param> |
063 |
private static void GetUserRecos(DoubanContext context) |
064 |
{ |
065 |
foreach (var item in context.Me.Recommends) |
066 |
{ |
067 |
item.Title.Dump(); |
068 |
069 |
//获取推荐回复 |
070 |
foreach (var cc in item.Comments) |
071 |
{ |
072 |
cc.Title.Dump(); |
073 |
} |
074 |
} |
075 |
} |
076 |
077 |
/// <summary> |
078 |
/// 获取指定城市id的活动 |
079 |
/// </summary> |
080 |
/// <param name="context"></param> |
081 |
private static void GetLocationEvents(DoubanContext context) |
082 |
{ |
083 |
var events = |
084 |
(from e in context.Events |
085 |
where e.Location.ID == "beijing" |
086 |
select e).Take(10); |
087 |
088 |
foreach (var item in events) |
089 |
{ |
090 |
item.Title.Dump(); |
091 |
} |
092 |
} |
093 |
094 |
/// <summary> |
095 |
/// 获取指定用户所有活动 |
096 |
/// </summary> |
097 |
/// <param name="context"></param> |
098 |
private static void GetUserEvents(DoubanContext context) |
099 |
{ |
100 |
// 用户参与的活动 |
101 |
//context.Me.ParticipateEvents |
102 |
// 用户感兴趣的活动 |
103 |
//context.Me.WishEvents |
104 |
// 用户发起的活动 |
105 |
//context.Me.InitiateEvents |
106 |
foreach (var item in context.Me.Events) |
107 |
{ |
108 |
item.Title.Dump(); |
109 |
} |
110 |
} |
111 |
112 |
/// <summary> |
113 |
/// 获取用户所有日记(延迟加载) |
114 |
/// </summary> |
115 |
/// <param name="context"></param> |
116 |
private static void GetUserNotes(DoubanContext context) |
117 |
{ |
118 |
foreach (var item in context.Me.Notes) |
119 |
{ |
120 |
item.Title.Dump(); |
121 |
} |
122 |
} |
123 |
124 |
/// <summary> |
125 |
/// 获取指定用户广播 |
126 |
/// </summary> |
127 |
/// <param name="context"></param> |
128 |
private static void GetUserMiniBlogs(DoubanContext context) |
129 |
{ |
130 |
var user = context.Peoples.GetByID( "ahbei" ); |
131 |
132 |
foreach (var item in user.MiniBlogs) |
133 |
{ |
134 |
item.Title.Dump(); |
135 |
136 |
// 获取广播回复 |
137 |
foreach (var c in item.Comments) |
138 |
{ |
139 |
c.Title.Dump(); |
140 |
} |
141 |
} |
142 |
} |
143 |
144 |
/// <summary> |
145 |
/// 获取友邻广播 |
146 |
/// </summary> |
147 |
/// <param name="context"></param> |
148 |
private static void GetContactMiniBlogs(DoubanContext context) |
149 |
{ |
150 |
foreach (var item in context.Me.ContactMiniBlogs) |
151 |
{ |
152 |
item.Title.Dump(); |
153 |
} |
154 |
} |
155 |
156 |
/// <summary> |
157 |
/// 获取指定用户收藏 |
158 |
/// </summary> |
159 |
/// <remarks> |
160 |
/// 此处以Me为例,也可以换成查询得来的People。当访问这些属性时,会自动加载数据 |
161 |
/// </remarks> |
162 |
/// <param name="context"></param> |
163 |
private static void GetPeopleCollections(DoubanContext context) |
164 |
{ |
165 |
// 获取音乐收藏 |
166 |
// context.Me.Musics |
167 |
// 获取电影收藏 |
168 |
// context.Me.Movies |
169 |
// 获取书籍搜藏 |
170 |
foreach (var item in context.Me.Books) |
171 |
{ |
172 |
item.Title.Dump(); |
173 |
} |
174 |
} |
175 |
176 |
/// <summary> |
177 |
/// 删除指定id的评论 |
178 |
/// </summary> |
179 |
/// <param name="context"></param> |
180 |
private static void DeleteReview(DoubanContext context) |
181 |
{ |
182 |
// 代码中的id更换为有效id |
183 |
var review = context.Reviews.GetByID( "2902263" ); |
184 |
context.Reviews.Delete(review.ID); |
185 |
} |
186 |
187 |
/// <summary> |
188 |
/// 更新指定的id的评论 |
189 |
/// </summary> |
190 |
/// <param name="context"></param> |
191 |
private static void UpdateReview(DoubanContext context) |
192 |
{ |
193 |
// 代码中的id更换为有效id |
194 |
var review = context.Reviews.GetByID( "2902263" ); |
195 |
review.Content = "Udpat content test for linq2douban" ; |
196 |
context.Reviews.Update(review.ID, review); |
197 |
} |
198 |
199 |
/// <summary> |
200 |
/// 发表评论 |
201 |
/// </summary> |
202 |
/// <remarks> |
203 |
/// 发表短的Content内容,douban api会报失败 |
204 |
/// </remarks> |
205 |
/// <param name="context"></param> |
206 |
private static void AddReview(DoubanContext context) |
207 |
{ |
208 |
var review = new Review |
209 |
{ |
210 |
// 如果Subject是从API读回来的,Source属性会自动赋值 |
211 |
Subject = new Movie { Source = "http://api.douban.com/movie/subject/1424406" }, |
212 |
Rating = new Rating { Value = 4 }, |
213 |
Content = "this is the test for linq2doubanddddddddddddddddddddddddddddddddddddddddd" , |
214 |
Title = "this is the test for linq2douban" |
215 |
}; |
216 |
217 |
context.Reviews.Insert(review); |
218 |
} |
219 |
220 |
/// <summary> |
221 |
/// 获取指定书籍/电影/音乐的评论 |
222 |
/// </summary> |
223 |
/// <param name="context"></param> |
224 |
private static void GetSubjectReviews(DoubanContext context) |
225 |
{ |
226 |
var movie = context.Movies.GetByID( "1424406" ); |
227 |
movie.Reviews.Count().Dump(); |
228 |
} |
229 |
230 |
/// <summary> |
231 |
/// 获取用户所有评论 |
232 |
/// </summary> |
233 |
/// <remarks> |
234 |
/// 此例用me做示例,获取指定的用户的评论,访问People.Reviews属性即可,框架会延迟加载 |
235 |
/// </remarks> |
236 |
/// <param name="context"></param> |
237 |
private static void GetReviews(DoubanContext context) |
238 |
{ |
239 |
foreach (var item in context.Me.Reviews) |
240 |
{ |
241 |
item.Title.Dump(); |
242 |
} |
243 |
} |
244 |
245 |
/// <summary> |
246 |
/// 示例复合查询(关键字,startindex,maxtresult) |
247 |
/// </summary> |
248 |
/// <remarks> |
249 |
/// douban的startindex, maxresult的含义与常识理解不通, |
250 |
/// douban的maxresult表示取回数据的最大下标,所以Take(20).Skip(10)返回下标为10-20共11条数据 |
251 |
/// </remarks> |
252 |
/// <param name="context"></param> |
253 |
private static void GetBooks(DoubanContext context) |
254 |
{ |
255 |
var query = context.Books.Has( "新东方" ).Take(20).Skip(10); |
256 |
257 |
foreach (var item in query) |
258 |
{ |
259 |
item.Title.Dump(); |
260 |
} |
261 |
} |
262 |
263 |
/// <summary> |
264 |
/// 用多个条件查询书籍(电影、音乐等,查询同此例) |
265 |
/// </summary> |
266 |
/// <remarks> |
267 |
/// LINQToolKit会根据queries.config里定义的query rules转换成相应的url进行查询, |
268 |
/// 你可尝试用不同关键字匹配,如果有问题请发chwkai@gmail.com |
269 |
/// </remarks> |
270 |
/// <param name="context"></param> |
271 |
private static void GetBooksByQuery(DoubanContext context) |
272 |
{ |
273 |
var query = |
274 |
from b in context.Books |
275 |
where b.LongIsbn == "9787543639133" || b.ID == "2023013" |
276 |
select b; |
277 |
278 |
foreach (var item in query) |
279 |
{ |
280 |
item.Title.Dump(); |
281 |
} |
282 |
} |
283 |
284 |
/// <summary> |
285 |
/// 获取指定ID的书籍 |
286 |
/// </summary> |
287 |
/// <remarks> |
288 |
/// 获取指定ID的douban信息与此例相同 |
289 |
/// </remarks> |
290 |
/// <param name="context"></param> |
291 |
private static void GetBookByID(DoubanContext context) |
292 |
{ |
293 |
var query = |
294 |
from b in context.Books |
295 |
where b.ID == "2023013" |
296 |
select b; |
297 |
query.Single().Dump(); |
298 |
} |
299 |
300 |
/// <summary> |
301 |
/// 获取用户关注的人(延迟加载) |
302 |
/// </summary> |
303 |
/// <param name="context"></param> |
304 |
private static void GetContacts(DoubanContext context) |
305 |
{ |
306 |
// context.Me.Contacts 获取当前用户关注的人 |
307 |
308 |
var query = |
309 |
from p in context.Peoples |
310 |
where p.ID == "chwkai" |
311 |
select p; |
312 |
313 |
// People.Contacts 当需要访问时会延迟加载 |
314 |
query.Single().Contacts.Count().Dump(); |
315 |
} |
316 |
317 |
/// <summary> |
318 |
/// 获取用户朋友(延迟加载) |
319 |
/// </summary> |
320 |
/// <param name="context"></param> |
321 |
private static void GetFriends(DoubanContext context) |
322 |
{ |
323 |
// context.Me.Friends 获取当前用户的朋友 |
324 |
325 |
var query = |
326 |
from p in context.Peoples |
327 |
where p.ID == "chwkai" |
328 |
select p; |
329 |
330 |
// People.Friends 当需要访问时会延迟加载 |
331 |
query.Single().Friends.Count().Dump(); |
332 |
} |
333 |
334 |
/// <summary> |
335 |
/// 关键字搜索用户 |
336 |
/// </summary> |
337 |
/// <remarks> |
338 |
/// 不是ID的相等比较条件都会转换为关键字查询 |
339 |
/// </remarks> |
340 |
/// <param name="context"></param> |
341 |
private static void GetUserByKey2(DoubanContext context) |
342 |
{ |
343 |
var query = |
344 |
from p in context.Peoples |
345 |
where p.Title == "net" |
346 |
select p; |
347 |
query.Count().Dump(); |
348 |
} |
349 |
350 |
/// <summary> |
351 |
/// 关键字搜索用户 |
352 |
/// </summary> |
353 |
/// <param name="context"></param> |
354 |
private static void GetUserByKey(DoubanContext context) |
355 |
{ |
356 |
var query = context.Peoples.Has( "net" ); |
357 |
query.Count().Dump(); |
358 |
} |
359 |
360 |
/// <summary> |
361 |
/// 获取当前用户(需要授权) |
362 |
/// </summary> |
363 |
/// <param name="context"></param> |
364 |
private static void GetCurrentUser(DoubanContext context) |
365 |
{ |
366 |
context.Me.Content.Dump(); |
367 |
} |
368 |
369 |
/// <summary> |
370 |
/// 获取单个用户信息 |
371 |
/// </summary> |
372 |
/// <param name="context"></param> |
373 |
private static void GetOneUserLinqStyle(DoubanContext context) |
374 |
{ |
375 |
var user = |
376 |
from u in context.Peoples |
377 |
where u.ID == "chwkai" |
378 |
select u; |
379 |
user.Single().Content.Dump(); |
380 |
} |
381 |
382 |
/// <summary> |
383 |
/// 获取单个用户信息 |
384 |
/// </summary> |
385 |
/// <param name="context"></param> |
386 |
private static void GetOneUser(DoubanContext context) |
387 |
{ |
388 |
var user = context.Peoples.GetByID( "chwkai" ); |
389 |
user.Content.Dump(); |
390 |
} |