.net Mongo Driver 1.0与2.0的对比与2.0的优化

前言

  最近闲的时间有点多,因此仍是写博客吧。数据库

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

  Mongo C#驱动1.0到2.0设计方面的差异很是大。c#

正文

先说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方法与数据库中执行构建查询的方法混在一块儿,这点是能够改进的。不然可能出现一下问题:this

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

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

 

 

这样看起来没问题,可是在使用时,以下代码:翻译

这是段经常使用的分页代码,我天真的觉得他会将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的,必定要尝试着去说服他……额……

相关文章
相关标签/搜索