首頁 後端開發 C#.Net教程 擴充MongoDB C# Driver的QueryBuilder

擴充MongoDB C# Driver的QueryBuilder

Feb 28, 2017 am 11:53 AM

擴展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 的內容,更多相關內容請關注PHP中文網(www.php.cn)!


#
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
C#與C:歷史,進化和未來前景 C#與C:歷史,進化和未來前景 Apr 19, 2025 am 12:07 AM

C#和C 的歷史與演變各有特色,未來前景也不同。 1.C 由BjarneStroustrup在1983年發明,旨在將面向對象編程引入C語言,其演變歷程包括多次標準化,如C 11引入auto關鍵字和lambda表達式,C 20引入概念和協程,未來將專注於性能和系統級編程。 2.C#由微軟在2000年發布,結合C 和Java的優點,其演變注重簡潔性和生產力,如C#2.0引入泛型,C#5.0引入異步編程,未來將專注於開發者的生產力和雲計算。

使用 Composer 解決推薦系統的困境:andres-montanez/recommendations-bundle 的實踐 使用 Composer 解決推薦系統的困境:andres-montanez/recommendations-bundle 的實踐 Apr 18, 2025 am 11:48 AM

在開發一個電商網站時,我遇到了一個棘手的問題:如何為用戶提供個性化的商品推薦。最初,我嘗試了一些簡單的推薦算法,但效果並不理想,用戶的滿意度也因此受到影響。為了提升推薦系統的精度和效率,我決定採用更專業的解決方案。最終,我通過Composer安裝了andres-montanez/recommendations-bundle,這不僅解決了我的問題,還大大提升了推薦系統的性能。可以通過一下地址學習composer:學習地址

CentOS上GitLab的數據庫如何選擇 CentOS上GitLab的數據庫如何選擇 Apr 14, 2025 pm 04:48 PM

CentOS系統上GitLab數據庫部署指南選擇合適的數據庫是成功部署GitLab的關鍵步驟。 GitLab兼容多種數據庫,包括MySQL、PostgreSQL和MongoDB。本文將詳細介紹如何選擇並配置這些數據庫。數據庫選擇建議MySQL:一款廣泛應用的關係型數據庫管理系統(RDBMS),性能穩定,適用於大多數GitLab部署場景。 PostgreSQL:功能強大的開源RDBMS,支持複雜查詢和高級特性,適合處理大型數據集。 MongoDB:流行的NoSQL數據庫,擅長處理海

CentOS MongoDB備份策略是什麼 CentOS MongoDB備份策略是什麼 Apr 14, 2025 pm 04:51 PM

CentOS系統下MongoDB高效備份策略詳解本文將詳細介紹在CentOS系統上實施MongoDB備份的多種策略,以確保數據安全和業務連續性。我們將涵蓋手動備份、定時備份、自動化腳本備份以及Docker容器環境下的備份方法,並提供備份文件管理的最佳實踐。手動備份:利用mongodump命令進行手動全量備份,例如:mongodump-hlocalhost:27017-u用戶名-p密碼-d數據庫名稱-o/備份目錄此命令會將指定數據庫的數據及元數據導出到指定的備份目錄。

c#.net的持續相關性:查看當前用法 c#.net的持續相關性:查看當前用法 Apr 16, 2025 am 12:07 AM

C#.NET依然重要,因為它提供了強大的工具和庫,支持多種應用開發。 1)C#結合.NET框架,使開發高效便捷。 2)C#的類型安全和垃圾回收機制增強了其優勢。 3).NET提供跨平台運行環境和豐富的API,提升了開發靈活性。

Debian MongoDB如何進行數據加密 Debian MongoDB如何進行數據加密 Apr 12, 2025 pm 08:03 PM

在Debian系統上為MongoDB數據庫加密,需要遵循以下步驟:第一步:安裝MongoDB首先,確保您的Debian系統已安裝MongoDB。如果沒有,請參考MongoDB官方文檔進行安裝:https://docs.mongodb.com/manual/tutorial/install-mongodb-on-debian/第二步:生成加密密鑰文件創建一個包含加密密鑰的文件,並設置正確的權限:ddif=/dev/urandomof=/etc/mongodb-keyfilebs=512

mongodb怎麼設置用戶 mongodb怎麼設置用戶 Apr 12, 2025 am 08:51 AM

要設置 MongoDB 用戶,請按照以下步驟操作:1. 連接到服務器並創建管理員用戶。 2. 創建要授予用戶訪問權限的數據庫。 3. 使用 createUser 命令創建用戶並指定其角色和數據庫訪問權限。 4. 使用 getUsers 命令檢查創建的用戶。 5. 可選地設置其他權限或授予用戶對特定集合的權限。

從網絡到桌面:C#.NET的多功能性 從網絡到桌面:C#.NET的多功能性 Apr 15, 2025 am 12:07 AM

C#.NETisversatileforbothwebanddesktopdevelopment.1)Forweb,useASP.NETfordynamicapplications.2)Fordesktop,employWindowsFormsorWPFforrichinterfaces.3)UseXamarinforcross-platformdevelopment,enablingcodesharingacrossWindows,macOS,Linux,andmobiledevices.

See all articles