扩展MongoDB C# Driver的QueryBuilder
因为不想直接hardcode "ClassA.MemberA.MemberB" 这种字符串 。写了下面几个类,用于下面经常使用的场景:
1. 表达式转换成字符串函数: ExpToStr()
2. Collection函数:当有集合成员时,能够使用此类,将返回QueryCollection对象,这个类的代码之后附上
3. CollectionAs函数:当使用了继承。希望将基类转换为子类并返回子类的QueryCollection
使用演示样例:
//获得表达式的字符串形式
1. QueryEx<ClassA>.ExpToStr ((ClassA m)=> m.MemberA.MemberB.MemberC) //集合.成员.字段
//PoppedSegments为集合,AssignedNetwork.Name为成员
//将返回PoppedSegments.AssignedNetwork.Name
2. QueryEx<MDDelivery>.Collection(x => x.PoppedSegments).Matches(p => p.AssignedNetwork.Name, bsonRegex), //子类集合.成员.字段
//STPaymentTransaction为基类,STPaymentCompanyCredit为子类,Company字段在子类中
//将返回Payments.Company.Name
3. QueryEx<MDDelivery>.CollectionAs<STPaymentTransaction, STPaymentCompanyCredit>(x=>x.Payments).Matches(p=>p.Company.Name, bsonRegex) //集合.集合.成员.字段
//Parcels为集合,STCustomPropertyRuntime为基类,STNumericPropertyRuntime为子类,CustomProps为STNumericPropertyRuntime中成员,Value为CustomProp中成员
//将返回Parcels.CustomProps.Value
4. QueryEx<MDDelivery>.Collection(x=>x.Parcels).CollectionMemberAs<STCustomPropertyRuntime, STNumericPropertyRuntime>(p=>p.CustomProps).Matches(p=>p.Value, bsonRegex),
实现代码:
public class QueryEx<TDocument>
{
public static QueryCollection<TDocument, TCollection> Collection<TCollection>(
Expression<Func<TDocument, IEnumerable<TCollection>>> collectionExpression)
{
return new QueryCollection<TDocument, TCollection>(collectionExpression);
} //for those cases using inheritance
//e.g STPaymentTransaction
//Payments will return STPaymentTransaction
//need to cast to sub classes(STPaymentCompanyCredit) so that be able to filter by child members (e.g. Company)
public static QueryCollection<TDocument, TSub> CollectionAs<TCollection, TSub>(
Expression<Func<TDocument, IEnumerable<TCollection>>> collectionExpression)
where TSub : TCollection
{
var argParam = Expression.Parameter(typeof (TDocument), "x");
var memberStr = ExpToStr(collectionExpression);
MemberExpression nameProperty = Expression.Property(argParam, memberStr); var subExp = Expression.Convert(nameProperty, typeof(IEnumerable<TSub>)); var exp = Expression.Lambda<Func<TDocument, IEnumerable<TSub>>>(
subExp,
argParam); return new QueryCollection<TDocument, TSub>(exp);
} /// <summary>
/// return string value for a expression:
/// for s.Name.Val1.Val2 will return Name.Val1.Val2
/// </summary>
/// <typeparam name="MDClass"></typeparam>
/// <typeparam name="Member"></typeparam>
/// <param name="exp"></param>
/// <returns></returns>
public static string ExpToStr<TDocument, Member>(Expression<Func<TDocument, Member>> exp)
{
return new QueryExpressionHelper().MemberExpression(exp);
}
} public class QueryCollection<TDocument, TCollection>
{
private readonly QueryExpressionHelper _queryExpression;
private string _collectionName; public string Context
{
get { return _collectionName; }
} public QueryCollection(Expression<Func<TDocument, IEnumerable<TCollection>>> collectionExpression)
{
_queryExpression = new QueryExpressionHelper();
_collectionName = _queryExpression.MemberExpression(collectionExpression);
} public QueryMember<TCollection, TMember> Member<TMember>(Expression<Func<TCollection, TMember>> exp)
{
var expStr = QueryEx<TCollection>.ExpToStr(exp);
var context = string.Format("{0}.{1}", _collectionName, expStr);
var obj = new QueryMember<TCollection, TMember>(context); return obj;
} public QueryCollection<TCollection, TMember> CollectionMember<TMember>(
Expression<Func<TCollection, IEnumerable<TMember>>> exp)
{
var expStr = QueryEx<TCollection>.ExpToStr(exp);
var obj = new QueryCollection<TCollection, TMember>(exp)
{
_collectionName = string.Format("{0}.{1}", _collectionName, expStr)
}; return obj;
} /// <summary>
/// this method only support 1 layer nested(not for Query Collection.Collection , but for Collection.Member)
/// if member is collection and need convert to sub class
/// </summary>
/// <typeparam name="TMember">Base Type</typeparam>
/// <typeparam name="TMemberSub">Child Class Type</typeparam>
/// <param name="collectionExpression"></param>
/// <returns></returns>
public QueryCollection<TCollection, TMemberSub> CollectionMemberAs<TMember, TMemberSub>(
Expression<Func<TCollection, IEnumerable<TMember>>> collectionExpression)
where TMemberSub : TMember
{
var obj = QueryEx<TCollection>.CollectionAs<TMember, TMemberSub>(collectionExpression);
obj._collectionName = string.Format("{0}.{1}", _collectionName, obj._collectionName); return obj;
} public IMongoQuery LT<TMember>(Expression<Func<TCollection, TMember>> memberExpression, TMember value)
{
var memberName = _queryExpression.MemberExpression(memberExpression); return Query.LT(string.Format("{0}.{1}", _collectionName, memberName), BsonValue.Create(value));
} public IMongoQuery LT<TValue>(Expression<Func<TCollection, IEnumerable<TValue>>> memberExpression, TValue value)
{
var memberName = _queryExpression.MemberExpression(memberExpression); return Query.LT(string.Format("{0}.{1}", _collectionName, memberName), BsonValue.Create(value));
} public IMongoQuery EQ<TMember>(Expression<Func<TCollection, TMember>> memberExpression, TMember value)
{
var memberName = _queryExpression.MemberExpression(memberExpression); return Query.EQ(string.Format("{0}.{1}", _collectionName, memberName), BsonValue.Create(value));
} public IMongoQuery EQ<TValue>(Expression<Func<TCollection, IEnumerable<TValue>>> memberExpression, TValue value)
{
var memberName = _queryExpression.MemberExpression(memberExpression); return Query.EQ(string.Format("{0}.{1}", _collectionName, memberName), BsonValue.Create(value));
} public IMongoQuery NE<TMember>(Expression<Func<TCollection, TMember>> memberExpression, TMember value)
{
var memberName = _queryExpression.MemberExpression(memberExpression); return Query.NE(string.Format("{0}.{1}", _collectionName, memberName), BsonValue.Create(value));
} public IMongoQuery NE<TValue>(Expression<Func<TCollection, IEnumerable<TValue>>> memberExpression, TValue value)
{
var memberName = _queryExpression.MemberExpression(memberExpression); return Query.NE(string.Format("{0}.{1}", _collectionName, memberName), BsonValue.Create(value));
} public IMongoQuery In<TMember>(Expression<Func<TCollection, TMember>> memberExpression, params TMember[] values)
{
return In<TMember>(memberExpression, new List<TMember>(values));
} public IMongoQuery In<TMember>(Expression<Func<TCollection, TMember>> memberExpression,
IEnumerable<TMember> values)
{
var memberName = _queryExpression.MemberExpression(memberExpression);
return Query.In(string.Format("{0}.{1}", _collectionName, memberName), values.Select(x => BsonValue.Create(x)));
} public IMongoQuery In<TCastC, TMember>(Expression<Func<TCastC, TMember>> memberExpression,
IEnumerable<TMember> values) where TCastC : TCollection
{
var memberName = _queryExpression.MemberExpression(memberExpression);
return Query.In(string.Format("{0}.{1}", _collectionName, memberName), values.Select(x => BsonValue.Create(x)));
} public IMongoQuery In<TValue>(Expression<Func<TCollection, IEnumerable<TValue>>> memberExpression, IEnumerable<TValue> values)
{
var memberName = _queryExpression.MemberExpression(memberExpression);
return Query.In(string.Format("{0}.{1}", _collectionName, memberName), values.Select(x => BsonValue.Create(x)));
} public IMongoQuery In<TCastC, TValue>(Expression<Func<TCastC, IEnumerable<TValue>>> memberExpression, IEnumerable<TValue> values) where TCastC : TCollection
{
var memberName = _queryExpression.MemberExpression(memberExpression);
return Query.In(string.Format("{0}.{1}", _collectionName, memberName), values.Select(x => BsonValue.Create(x)));
} public IMongoQuery Matches<TMember>(Expression<Func<TCollection, TMember>> memberExpression, BsonRegularExpression value)
{
var memberName = _queryExpression.MemberExpression(memberExpression); return Query.Matches(string.Format("{0}.{1}", _collectionName, memberName), value);
} public IMongoQuery Matches<TValue>(Expression<Func<TCollection, IEnumerable<TValue>>> memberExpression, BsonRegularExpression value)
{
var memberName = _queryExpression.MemberExpression(memberExpression); return Query.Matches(string.Format("{0}.{1}", _collectionName, memberName), value);
}
} public class QueryMember<TDocument, TCollection>
{
private readonly QueryExpressionHelper _queryExpression;
private string _collectionName; public string Context
{
get { return _collectionName; }
} public QueryMember(Expression<Func<TDocument, TCollection>> exp)
{
_queryExpression = new QueryExpressionHelper();
_collectionName = _queryExpression.MemberExpression(exp);
} public QueryMember(string context)
{
_collectionName = context;
} } public class QueryExpressionHelper
{
public string Context; public string MemberExpression<TMember>(Expression<TMember> expression)
{
MemberExpression me;
switch (expression.Body.NodeType)
{
case ExpressionType.MemberAccess:
me = expression.Body as MemberExpression;
break;
case ExpressionType.Convert:
dynamic convertedBody = expression.Body;
me = convertedBody.Operand as MemberExpression;
break; default:
throw new NotSupportedException(string.Format("Member with node type {0} is not supported. expression {1}", expression.Body.NodeType, expression));
}
var stack = new Stack<string>(); while (me != null)
{
stack.Push(me.Member.Name);
me = me.Expression as MemberExpression;
} var expStr = string.Join(".", stack.ToArray());
return expStr; }
} public static class QueryMoney
{
public static IMongoQuery Value(string name, double val)
{
var accuracy = 0.005; return Query.And(
Query.LT(name, new BsonDouble(val + accuracy)),
Query.GT(name, new BsonDouble(val - accuracy)));
}
}
扩展MongoDB C# Driver的QueryBuilder的更多相关文章
- 给java mongodb 官方driver 增加bean 操作
mongodb官方的java driver不支持直接插入java bean,只能使用DbObject的Key,Value形式进行insert,update,(c# mongodb官方driver类 ...
- MongoDB Java Driver操作指南
MongoDB为Java提供了非常丰富的API操作,相比关系型数据库,这种NoSQL本身的数据也有点面向对象的意思,所以对于Java来说,Mongo的数据结构更加友好. MongoDB在今年做了一次重 ...
- MongoDB C Driver使用教程
MongoDB C Driver使用教程 转载请注明出处http://www.cnblogs.com/oloroso/ 本指南提供简介 MongoDB C 驱动程序. 在 C API 的详细信息,请参 ...
- windows平台下安装、编译、使用mongodb C++ driver
本博客将记录在Win8.1 ,VS2013环境下编译.配置mongodb C++ driver的流程. 1.下载预备 下载Boost:http://sourceforge.net/projects/b ...
- Ignoring Extra Elements in mongoDB C# Driver
MongoDB删除字段后会报错: Element ... does not match any field or property of class Customer. 需要在实体类增加 [BsonI ...
- mongodb .net driver
1.介绍 The official MongoDB .NET Driver provides asynchronous interaction with MongoDB. Powering the d ...
- Mongodb Java Driver 参数配置解析
要正确使用Mongodb Java Driver,MongoClientOptions参数配置对数据库访问的并发性能影响极大. connectionsPerHost:与目标数据库能够建立的最大conn ...
- mongodb c++ driver(2.53)windows编译
编译环境: (1) 下载python2.7, 使用x86_32位,因为scons只有32位安装包可用: (2) 下载scons2.3.0,The current production release ...
- MongoDB C Driver and APIinstances linux MongoDB安装配置
<一,linux平台MongoDB安装配置>在这我们使用的Centos6 yum部署的,你想搞编译,自个干!
随机推荐
- JavaScript 笔记(3) -- JSON
JavaScript JSON (JavaScript Object Notation): 是一种轻量级的数据交换格式 JSON 是用于存储和传输数据的格式 JSON 通常用于服务端向网页传递数据 J ...
- Python(2)-- 运算符
1. 算术运算符 常规: 加(+).减(-).乘(*).除(/).取模(%) 此外: 幂(**):返回x的y次幂, eg: 2**3---返回 2 的 5 次幂,输出结果32 取整除(//):返回商的 ...
- 【02】webpack 之 入门
http://www.jianshu.com/p/42e11515c10f 写在前面的话 阅读本文之前,先看下面这个webpack的配置文件,如果每一项你都懂,那本文能带给你的收获也许就比较有限,你可 ...
- javascript屏蔽脏字
原文发布时间为:2009-04-16 -- 来源于本人的百度文章 [由搬家工具导入] <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tran ...
- 微信小程序 图片路径自动加上文件目录导致渲染报错问题
最近 在做小程序时候,发现一些商品图片在渲染时一直报错,也不显示,但是控制台打印出来 的路径却有没有问题 报错提示出错的路径会在前面自动加上“page/**”,思索了之后想到了微信只能解释https的 ...
- (3)Django 配置
一.settings django安装的应用程序 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.c ...
- Spring Cloud Feign 声明式服务调用
目录 一.Feign是什么? 二.Feign的快速搭建 三.Feign的几种姿态 参数绑定 继承特性 四.其他配置 Ribbon 配置 Hystrix 配置 一.Feign是什么? 通过对前面Sp ...
- c# datetime是一年中的第几周
public static int WeekOfYear(DateTime dt, CultureInfo ci) { return ci.Calendar.GetWeekOfYear(dt, ci. ...
- STM32命名
STM32产品命名 示例: STM32 F 100 C 6 T 6 B XXX 1 2 3 4 5 6 7 8 9 从上面的料号可以看出以下信息: ST品牌ARM Cortex-Mx系列内核32位超值 ...
- [转载]robo3t在Ubuntu 16.04中报错的解决方法
[问题] MongoDB的客户端robo3t在,Ubuntu 16.04中启动时报一个QT的错误: This application failed to start because it could ...