• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

扩展MongoDB C# Driver的QueryBuilder

c# 搞代码 4年前 (2022-01-09) 12次浏览 已收录 0个评论

扩展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.Name2. QueryEx<MDDelivery>.Collection(x => x.PoppedSegments).Matches(p => p.AssignedNetwork.Name, bsonRegex),//子类集合.成员.字段//STPaymentTransaction为基类,STPaymentCompanyCredit为子类,Company字段在子类中//将返回Payments.Company.Name3. QueryEx<MDDelivery>.CollectionAs<STPaymentTransaction, STPaymentCompanyCredit>(x=>x.Payments).Matches(p=>p.Company.Name, bsonRegex)//集合.集合.成员.字段//Parcels为集合,STCustomPropertyRuntime为基类,STNumericPropertyRuntime为子类,CustomProps为STNumericPropertyRuntime中成员,Value为CustomProp中成员//将返回Parcels.CustomProps.Value4. 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 NotSuppor<a>本文来源gao($daima.com搞@代@#码(网</a>tedException(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 的内容,更多相关内容请关注搞代码(www.gaodaima.com)!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:扩展MongoDB C# Driver的QueryBuilder
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址