擴充MongoDB C# Driver的QueryBuilder

來源:互聯網
上載者:User
擴充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 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 的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.