扩展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)!

C#和.NET提供了强大的功能和高效的开发环境。1)C#是一种现代、面向对象的编程语言,结合了C 的强大和Java的简洁性。2).NET框架是一个用于构建和运行应用程序的平台,支持多种编程语言。3)C#中的类和对象是面向对象编程的核心,类定义数据和行为,对象是类的实例。4).NET的垃圾回收机制自动管理内存,简化开发者的工作。5)C#和.NET提供了强大的文件操作功能,支持同步和异步编程。6)常见错误可以通过调试器、日志记录和异常处理来解决。7)性能优化和最佳实践包括使用StringBuild

.NETFramework是一个跨语言、跨平台的开发平台,提供一致的编程模型和强大的运行时环境。1)它由CLR和FCL组成,CLR管理内存和线程,FCL提供预构建功能。2)使用示例包括读取文件和LINQ查询。3)常见错误涉及未处理异常和内存泄漏,需使用调试工具解决。4)性能优化可通过异步编程和缓存实现,保持代码可读性和可维护性是关键。

C#.NET保持持久吸引力的原因包括其出色的性能、丰富的生态系统、强大的社区支持和跨平台开发能力。1)性能表现优异,适用于企业级应用和游戏开发;2).NET框架提供了广泛的类库和工具,支持多种开发领域;3)拥有活跃的开发者社区和丰富的学习资源;4).NETCore实现了跨平台开发,扩展了应用场景。

C#.NET中的设计模式包括Singleton模式和依赖注入。1.Singleton模式确保类只有一个实例,适用于需要全局访问点的场景,但需注意线程安全和滥用问题。2.依赖注入通过注入依赖提高代码灵活性和可测试性,常用于构造函数注入,但需避免过度使用导致复杂度增加。

C#.NET在现代世界中广泛应用于游戏开发、金融服务、物联网和云计算等领域。1)在游戏开发中,通过Unity引擎使用C#进行编程。2)金融服务领域,C#.NET用于开发高性能的交易系统和数据分析工具。3)物联网和云计算方面,C#.NET通过Azure服务提供支持,开发设备控制逻辑和数据处理。

C#.NET开发者社区提供了丰富的资源和支持,包括:1.微软的官方文档,2.社区论坛如StackOverflow和Reddit,3.GitHub上的开源项目,这些资源帮助开发者从基础学习到高级应用,提升编程技能。

C#.NET的优势包括:1)语言特性,如异步编程简化了开发;2)性能与可靠性,通过JIT编译和垃圾回收机制提升效率;3)跨平台支持,.NETCore扩展了应用场景;4)实际应用广泛,从Web到桌面和游戏开发都有出色表现。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

WebStorm Mac版
好用的JavaScript开发工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SublimeText3汉化版
中文版,非常好用

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境