扩展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部署的,你想搞编译,自个干!
随机推荐
- pat 团体天梯赛 L2-011. 玩转二叉树
L2-011. 玩转二叉树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜 ...
- MongoDB 查询语法
转载 http://blog.163.com/lgh_2002/blog/static/440175262012052116455/ 详见官方的手册:http://www.mongodb.org/di ...
- 控制台或Winform程序中如何编码或解码Server.URLEncode
原文发布时间为:2010-07-10 -- 来源于本人的百度文章 [由搬家工具导入] 在Asp.net中可以使用Server.HTMLEncode和Server.URLEncode 将文本或URL的特 ...
- Manjaro linux软件源设置
1.从官方http://jaist.dl.sourceforge.net/project/manjarotest/16.06-dev/kde/minimal/manjaro-kde-minimal-1 ...
- 用python获取服务器硬件信息[转]
#!/usr/bin/env python # -*- coding: utf-8 -*- import rlcompleter, readline readline.parse_and_bind(' ...
- Eigen--简单的C++矩阵计算库
晚上突然想写一段小C++程序,要用到矩阵求逆呀乘法呀之类的,所以找了一下有什么现成的可用的C++矩阵计算相关的库,发现有一大堆,在其中各种各样的配置,感觉比较麻烦.从方便性来说Eigen是最方便的了, ...
- AC日记——幸运号码 51nod 1043
幸运号码 思路: 传说中的数位dp: 不难发现,n(n<1000) ,那么,n个数的最大和为9*1000=9000: 对于9000*1000的时间范围,我们可以用dp来解决: dp[i][j], ...
- Java面试中的多线程问题
很多核心 Java 面试题来源于多线程(Multi-Threading)和集合框架(Collections Framework),理解核心线程概念时,娴熟的实际经验是必需的.这篇文章收集了 Java ...
- workflow engine Ruote初体验之三(条件与美元符号)
条件 我们可以用:if和:unless公共属性来进行条件判断,或者使用if,given,once或者equals(已经过时)关键字. 使用:if属性: 1 cursor do 2 participan ...
- 基于WPF系统框架设计(3)-Fluent Ribbon界面布局
一个系统框架除了功能菜单导航,有系统内容显示区域,系统状态栏. Silver: Blue: Black: 系统界面设计,就不进行技术细节介绍了,主题以框架设计为主,Xaml源码参考: <Flue ...