zoukankan      html  css  js  c++  java
  • .net Mongo Driver 1.0与2.0的对比与2.0的优化

    前言

      最近闲的时间有点多,所以还是写博客吧。

      有人说Mongo 2.0的写法难以把控,好多地方不知道咋用,所以坚持用1.0(不愿意去尝试2.0),我感觉不可理解。所以写篇博客比较下。

      Mongo C#驱动1.0到2.0设计方面的差别非常大。

    正文

    先说1.0吧,更像是Mongo 各功能的直译,所以写法与mongo原生查询修改等比较类似,易上手。但是设计上确实存在很多问题。简单说几点:


    a.在query的构建方面,虽然有问题,但是勉强能接受

    1  var modelCursor = collection.Find(
    2                 Query.And(Query.Matches("Name", "test"),Query.EQ("Age",10),Query.In("id",new BsonArray(){"123","456","sda"})));
    3 var modelCursor1 = collection.Find(
    4                Query.And(Query<TestData>.Matches(t => t.Name, "test"), Query<TestData>.EQ(t=>t.Age, 10), Query<TestData>.In(t=>t._id, new BsonArray() { "123", "456", "sda" })));

    第一种方式代码简单,但是硬字符串比较多,万一改个字段,维护难度大

    第二种方式代码维护性好,但是代码真是烦琐,每个query都要来个泛型约定,冗余太多了

    b.大量linq方法与数据库中执行构建查询的方法混在一起,这点是可以改进的。否则可能出现一下问题:

    在查询返回类型上MongoCursor<TDefaultDocument>。继承IEnumerable<T>,Find时只是构建查询而已,只有调用GetEnumerator()才回去数据库查询数据。也就是ToList()或者foreach的时候才去查询。这一点设计的没错跟ef一致的

    执行方式,看看源码截图:

    这样看起来没问题,但是在使用时,如下代码:

    这是段常用的分页代码,我天真的以为他会将cursor.Skip().Take()生成查询去数据库中执行再把200条结果返回给我。但是实际情况不是这样的

    其实已经把所有数据都拿出来了,只是在客户端使用了linq的Skip去跳过而已。

    正确的用法是:

    要使用cursor的Set开头的方法才是构建查询的。

    如果你学ef那也学彻底点啊,不信你看ef查询时的Skip

    人家把Skip Take都“重写”了好吧,根本没使用IEnumerable<T>的Skip。这一点想说明的,就是导致了大量的linq客户端执行的代码与Mongo服务端执行的代码混杂的问题

    c.另外分组查询是设计非常不好的。比如:

          

    请看GroupArgs的注释:

    知道我写这么多注释,为啥吗,我怕过两天我也不知道咋用的了。更别说让其他同事用了。一个分组查询居然还要在c#中写原始的js代码来实现。所以驱动在这里的实现只是半成品的。

    对比着再说说2.0吧,首先与时俱进大量采用了异步编程。然后对lamda表达式与强类型的支持都做了改进。


    a.首先查询全部是lamda表达式了,这次算是把查询这块彻底本地化了。不用再去记住Mongo查询原生的语法了,门槛很低了。如:

    b.重写了查询返回值类型,叫什么FindFluent。翻译过来就是可链式调用的东东,看看源码:

    果然都是返回的this便于链式调用,再看看里面的方法:

     

    2.0不再继承IEnumerable接口,里面的方法全部是自己实现的了,比如:

    findFluent.Skip(10).Limit(10).SortBy(t => t.Age);使用起来顺手多了,而且都是到数据库端执行的.

    就连取集合的First方法,也是经过服务端处理的,不信你看:

    你再看看Single方法:

    查询的时候都做了Limit处理,…………………………但是会不会突然心头一紧。怎么Single的时候find.Limit(2)啊,太奇怪了。不过聪明的小伙伴,想一会儿应该知道咋回事了,哈哈!

    再看看分组查询优化,我就不说了,把c#里写js代码的部分直接搞掉了。使用lamda表达式的方式实现了,如下:

    var dataGroup = collection.Aggregate().Group(t => t.Age, g => new { _id = g.Key, TotalAge = g.Sum(x => x.Age) });

    需要注意的是2.0都是异步编程,熟悉下用法就行了,这也是.net4.5比较大的改变:把异步编程变得简单。

    先写这么多了,那里说的不对的地方大家多多指出。另外身边有谁还坚持用1.0的,一定要尝试着去说服他……额……

    ——我认识一个人,他每做一件小事都像救命稻草一样抓着。有一天我发现,豁!他抱着的已经是让我仰望的参天大树了.
  • 相关阅读:
    jQuery height()、innerHeight()、outerHeight()函数的区别
    [css][移动设备]禁止横竖屏时内容自动调整
    document模板
    CSS3的appearance属性--改变元素的外观
    jQuery API中文文档
    jquery 获取元素的 实际宽度和高度
    为什么使用"use strict"可以节约你的时间
    ueditor的过滤、转义、格式丢失问题
    flask mysql
    WPF进阶之接口(2):IDisposable,ICollectionView
  • 原文地址:https://www.cnblogs.com/SpringRen/p/4613588.html
Copyright © 2011-2022 走看看