• MongoDB学习笔记~关于官方驱动集成IQueryable之后的一些事


    回到目录

    关于官方驱动集成IQueryable之后的一些事,有好事也有坏事,好事就是它会将你的linq语句非常友好的翻译成MongoDB语句,而坏事就是有一些linq语句不会被翻译,不会被翻译的代价就是将整个结果集装到内存,然后进行linq to object的查询,效率自然是非常低的,呵呵。

    好事

    最新官方驱动中,添加了对IQueryable扩展方法的支持

            public static IMongoQueryable<TDocument> AsQueryable<TDocument>(this IMongoCollection<TDocument> collection);

    1 它对Where完成支持

    _webManageUsersRepository.GetModel().Where(i => i.LoginName == "zzl");

    2 它对group完全支持

     var g = _webManageUsersRepository.GetModel()
                    .GroupBy(i => i.DepartmentID, (i, v) => new 
                    {
                        dept = i,
                        userCount = v.Count()
                    });

    通过断点我们可以看到它所生成的mongodb语句,然后可以把语句放在命令行中去执行看看具体效果

    db.WebManageUsers.aggregate([{ "$group" : { "_id" : "$DepartmentID", "userCount" : { "$sum" : 1 } } }])

    上面写法是我比较喜欢的lambda表达式的方法,语法简介,漂亮,而我不太喜欢linq写法,但是,如果是多字段的分组,你就必须使用linq标准写法了,因为到目前为止,mongo官方驱动还不支持多字段分组的lambda写法,如下面的代码,分组结果就是错误的

     var bb = _webManageUsersRepository.GetModel()
                    .GroupBy(
                    i => new
                    {
                        i.DepartmentID,
                        i.Status
                    },
                    (i, v) => new
                    {
                        dept = i.DepartmentID,
                        status = i.Status,
                        userCount = v.Count()
                    });

    它不能正确的翻译成Mongo表达式

    {aggregate([{ "$group" : { "dept" : "$DepartmentID", "status" : "$Status", "userCount" : { "$sum" : 1 }, "_id" : 0 } }])}

    而使用传统的linq写法就可以被mongo驱动很好的翻译

      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()
                         };

    下面生成的代码是正确的

    aggregate([{ "$group" : { "_id" : { "dept" : "$DepartmentID", "status" : "$Status" }, "__agg0" : { "$sum" : 1 } } }, { "$project" : { "dept" : "$_id.dept", "status" : "$_id.status", "userCount" : "$__agg0", "_id" : 0 } }])}

    可以在mongo客户端上看到正确的结果

    坏事

    对count()方法完成不支持,不推荐使用,如果要用到count(),建议使用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;

    回到目录

  • 相关阅读:
    C语言 · 最小公倍数
    SSH实战 · SSH项目开发环境搭建
    C语言 · 回文数
    C语言 · 特殊回文数
    C语言 · 查找整数
    SSH实战 · SSH项目中怎么玩验证码
    SSH实战 · JAVA发送邮件相关
    SSH实战 · AJAX异步校验
    C语言 · 打印1-200之间的素数
    Jenkins权限设计错误解决办法
  • 原文地址:https://www.cnblogs.com/lori/p/4483890.html
Copyright © 2020-2023  润新知