扩展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部署的,你想搞编译,自个干!
随机推荐
- pom.xml(Project Object Model) 文件简单介绍
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...
- Mysql存储过程给变量赋值的几种方法实践
BEGIN DECLARE v_request_count INT; #申请次数 DECLARE v_plan_count INT; #安排次数 DECLARE v_learn_count INT; ...
- BZOJ 3940: [Usaco2015 Feb]Censoring
3940: [Usaco2015 Feb]Censoring Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 367 Solved: 173[Subm ...
- Javascript&Html-弹出窗口的屏蔽程序
大多数的浏览器都内置了弹出窗口的屏蔽程序,即使没有内置此类屏蔽程序的浏览器,用户也可以安装Yahoo tool等带有内置屏蔽程序的应用工具. 结果就是用户可以将绝大多数弹出窗口屏蔽掉. 于是,再弹出窗 ...
- SQLServer Split
ALTER FUNCTION dbo.splitl ( @String VARCHAR(MAX), @Delimiter VARCHAR(MAX) ) RETURNS @temptable TABLE ...
- ++x和x++
#include <stdio.h> int main() { int a,b,c=1,d=1; a = c++; b = ++d; printf("%d\t%d\n" ...
- LeetCode OJ--Sum Root to Leaf Numbers
https://oj.leetcode.com/problems/sum-root-to-leaf-numbers/ 给一棵树,找从根到叶的路径,并把路径上的数相加,求和. 树的深度优先搜索 /** ...
- 分享Kali Linux 2017.1镜像
分享Kali Linux 2017.1镜像 Kali Linux官方于4月24日发布Kali Linux 2017.1版本.该版本仍然采用滚动更新方式,所以软件源为kali-rolling.至现在分 ...
- Oracle并发控制、事务管理学习笔记
(a)基本概念 锁的2种最基本.最简单的类型:排他锁(eXclusive lock,即X锁).共享锁(Share lock,即S锁). 不同级别的锁定协议及其作用: 申请的锁 及其作用 锁定协议 修改 ...
- luogu P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows
题目描述 Each of Farmer John's N (4 <= N <= 16) cows has a unique serial number S_i (1 <= S_i & ...