MongoDB學習筆記~關(guan)于官方驅動集(ji)成IQueryable之后的一些事(shi)
關于官方驅(qu)動(dong)集(ji)成(cheng)IQueryable之后的一(yi)些(xie)事,有好事也有壞事,好事就是它會(hui)將(jiang)你的linq語句非常友好的翻譯成(cheng)MongoDB語句,而壞事就是有一(yi)些(xie)linq語句不(bu)會(hui)被(bei)翻譯,不(bu)會(hui)被(bei)翻譯的代價就是將(jiang)整(zheng)個結(jie)果集(ji)裝到(dao)內存,然(ran)后進行linq to object的查詢,效率自然(ran)是非常低的,呵呵。
好事
最新官方驅動(dong)中,添加了對IQueryable擴展方法的支(zhi)持(chi)
public static IMongoQueryable<TDocument> AsQueryable<TDocument>(this IMongoCollection<TDocument> collection);
1 它對Where完成(cheng)支持
_webManageUsersRepository.GetModel().Where(i => i.LoginName == "zzl");
2 它(ta)對(dui)group完全支(zhi)持
var g = _webManageUsersRepository.GetModel() .GroupBy(i => i.DepartmentID, (i, v) => new { dept = i, userCount = v.Count() });
通(tong)過斷點(dian)我們可以看到它(ta)所(suo)生成的mongodb語句(ju),然(ran)后可以把(ba)語句(ju)放在命令行中去執(zhi)行看看具體(ti)效果
db.WebManageUsers.aggregate([{ "$group" : { "_id" : "$DepartmentID", "userCount" : { "$sum" : 1 } } }])
上面(mian)(mian)寫法(fa)是(shi)我比(bi)較(jiao)喜歡的(de)lambda表達式的(de)方(fang)法(fa),語法(fa)簡介(jie),漂亮,而我不太(tai)喜歡linq寫法(fa),但是(shi),如(ru)果是(shi)多字段的(de)分組(zu),你(ni)就(jiu)必須使用linq標(biao)準寫法(fa)了,因為(wei)到目前為(wei)止,mongo官方(fang)驅動(dong)還不支持多字段分組(zu)的(de)lambda寫法(fa),如(ru)下面(mian)(mian)的(de)代碼,分組(zu)結(jie)果就(jiu)是(shi)錯誤(wu)的(de)
var bb = _webManageUsersRepository.GetModel() .GroupBy( i => new { i.DepartmentID, i.Status }, (i, v) => new { dept = i.DepartmentID, status = i.Status, userCount = v.Count() });
它不能正確的翻譯成Mongo表達式(shi)
{aggregate([{ "$group" : { "dept" : "$DepartmentID", "status" : "$Status", "userCount" : { "$sum" : 1 }, "_id" : 0 } }])}
而使用傳統的linq寫法就(jiu)可以(yi)被mongo驅(qu)動很好(hao)的翻譯
var gg = from a in _webManageUsersRepository.GetModel() group a by new { dept = a.DepartmentID, status = a.Status } into g select new RoleCount { dept = g.Key.dept, status = g.Key.status, userCount = g.Count() };
下面生成的代碼是(shi)正確的
aggregate([{ "$group" : { "_id" : { "dept" : "$DepartmentID", "status" : "$Status" }, "__agg0" : { "$sum" : 1 } } }, { "$project" : { "dept" : "$_id.dept", "status" : "$_id.status", "userCount" : "$__agg0", "_id" : 0 } }])}
可以(yi)在mongo客戶端上看到正確的(de)結果
壞事
對count()方法完成不支持,不推(tui)薦使(shi)用,如果要(yao)用到count(),建(jian)議使(shi)用mongo原生態的,而不是linq的
Stopwatch sw1 = new Stopwatch(); sw1.Restart(); var a1 = _webManageUsersRepository.Count(i => true);//性能好 sw1.Stop(); var at1 = sw1.ElapsedMilliseconds; Stopwatch sw = new Stopwatch(); sw.Restart(); var a = _webManageUsersRepository.GetModel().Count();//性能差 sw.Stop(); var at = sw.ElapsedMilliseconds;