QueryBuilder for MongoDB C # Driver Extension
QueryBuilder for MongoDB C # Driver Extension
Because you do not want to directly use a string such as hardcode ClassA. MemberA. MemberB, you have written the following classes for the following common scenarios:
1. expression to string function: ExpToStr ()
2. Collection function: This class can be used when a Collection member exists. The QueryCollection object is returned. The code of this class is attached
3. CollectionAs function: When inheritance is used, you want to convert the base class to a subclass and return the QueryCollection of the subclass.
Example:
// Obtain the expression string format 1. QueryEx
. ExpToStr (ClassA m) => m. memberA. memberB. memberC) // set. member. the field // PoppedSegments is a set of AssignedNetwork. name is a member // PoppedSegments is returned. assignedNetwork. name2. QueryEx
. Collection (x => x. poppedSegments ). matches (p => p. assignedNetwork. name, bsonRegex), // a collection of child classes. member. the field // STPaymentTransaction is the base class, STPaymentCompanyCredit is the subclass, and the Company field is in the subclass // the Payments will be returned. company. name3. QueryEx
. CollectionAs
(X => x. payments ). matches (p => p. company. name, bsonRegex) // set. set. member. the field // Parcels is a set, and STCustomPropertyRuntime is the base class. STNumericPropertyRuntime is a subclass, CustomProps is a member of STNumericPropertyRuntime, and Value is a member of CustomProp. // Parcels is returned. customProps. value4. QueryEx
. Collection (x => x. Parcels). CollectionMemberAs
(P => p. CustomProps). Matches (p => p. Value, bsonRegex ),
Implementation Code:
public class QueryEx
{ public static QueryCollection
Collection
( Expression
>> collectionExpression) { return new QueryCollection
(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
CollectionAs
( Expression
>> 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
)); var exp = Expression.Lambda
>>( subExp, argParam); return new QueryCollection
(exp); } ///
/// return string value for a expression: /// for s.Name.Val1.Val2 will return Name.Val1.Val2 /// ///
///
///
///
public static string ExpToStr
(Expression
> exp) { return new QueryExpressionHelper().MemberExpression(exp); } }public class QueryCollection
{ private readonly QueryExpressionHelper _queryExpression; private string _collectionName; public string Context { get { return _collectionName; } } public QueryCollection(Expression
>> collectionExpression) { _queryExpression = new QueryExpressionHelper(); _collectionName = _queryExpression.MemberExpression(collectionExpression); } public QueryMember
Member
(Expression
> exp) { var expStr = QueryEx
.ExpToStr(exp); var context = string.Format({0}.{1}, _collectionName, expStr); var obj = new QueryMember
(context); return obj; } public QueryCollection
CollectionMember
( Expression
>> exp) { var expStr = QueryEx
.ExpToStr(exp); var obj = new QueryCollection
(exp) { _collectionName = string.Format({0}.{1}, _collectionName, expStr) }; return obj; } ///
/// 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 /// ///
Base Type
///
Child Class Type
///
///
public QueryCollection
CollectionMemberAs
( Expression
>> collectionExpression) where TMemberSub : TMember { var obj = QueryEx
.CollectionAs
(collectionExpression); obj._collectionName = string.Format({0}.{1}, _collectionName, obj._collectionName); return obj; } public IMongoQuery LT
(Expression
> memberExpression, TMember value) { var memberName = _queryExpression.MemberExpression(memberExpression); return Query.LT(string.Format({0}.{1}, _collectionName, memberName), BsonValue.Create(value)); } public IMongoQuery LT
(Expression
>> memberExpression, TValue value) { var memberName = _queryExpression.MemberExpression(memberExpression); return Query.LT(string.Format({0}.{1}, _collectionName, memberName), BsonValue.Create(value)); } public IMongoQuery EQ
(Expression
> memberExpression, TMember value) { var memberName = _queryExpression.MemberExpression(memberExpression); return Query.EQ(string.Format({0}.{1}, _collectionName, memberName), BsonValue.Create(value)); } public IMongoQuery EQ
(Expression
>> memberExpression, TValue value) { var memberName = _queryExpression.MemberExpression(memberExpression); return Query.EQ(string.Format({0}.{1}, _collectionName, memberName), BsonValue.Create(value)); } public IMongoQuery NE
(Expression
> memberExpression, TMember value) { var memberName = _queryExpression.MemberExpression(memberExpression); return Query.NE(string.Format({0}.{1}, _collectionName, memberName), BsonValue.Create(value)); } public IMongoQuery NE
(Expression
>> memberExpression, TValue value) { var memberName = _queryExpression.MemberExpression(memberExpression); return Query.NE(string.Format({0}.{1}, _collectionName, memberName), BsonValue.Create(value)); } public IMongoQuery In
(Expression
> memberExpression, params TMember[] values) { return In
(memberExpression, new List
(values)); } public IMongoQuery In
(Expression
> memberExpression, IEnumerable
values) { var memberName = _queryExpression.MemberExpression(memberExpression); return Query.In(string.Format({0}.{1}, _collectionName, memberName), values.Select(x => BsonValue.Create(x))); } public IMongoQuery In
(Expression
> memberExpression, IEnumerable
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
(Expression
>> memberExpression, IEnumerable
values) { var memberName = _queryExpression.MemberExpression(memberExpression); return Query.In(string.Format({0}.{1}, _collectionName, memberName), values.Select(x => BsonValue.Create(x))); } public IMongoQuery In
(Expression
>> memberExpression, IEnumerable
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
(Expression
> memberExpression, BsonRegularExpression value) { var memberName = _queryExpression.MemberExpression(memberExpression); return Query.Matches(string.Format({0}.{1}, _collectionName, memberName), value); } public IMongoQuery Matches
(Expression
>> memberExpression, BsonRegularExpression value) { var memberName = _queryExpression.MemberExpression(memberExpression); return Query.Matches(string.Format({0}.{1}, _collectionName, memberName), value); } }public class QueryMember
{ private readonly QueryExpressionHelper _queryExpression; private string _collectionName; public string Context { get { return _collectionName; } } public QueryMember(Expression
> exp) { _queryExpression = new QueryExpressionHelper(); _collectionName = _queryExpression.MemberExpression(exp); } public QueryMember(string context) { _collectionName = context; } }public class QueryExpressionHelper { public string Context; public string MemberExpression
(Expression
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
(); 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))); } }