如何在C#中使用Mongo查询语法查询内存对象列表?
解决C#中用Mongo查询语法过滤内存对象列表的问题
你遇到的错误是因为FilterDefinition.Inject()仅适用于MongoDB驱动针对数据库集合的LINQ查询(即IQueryable),不能直接用于内存中的IEnumerable(比如List的Where方法)。以下是两种可行的解决方案:
方案一:序列化对象为BsonDocument后匹配过滤器
将内存中的对象序列化为BsonDocument,再用Mongo的过滤器逻辑判断是否匹配:
using MongoDB.Bson; using MongoDB.Driver; public class Student { public string LastName { get; set; } public List<int> Scores { get; set; } } // 初始化内存列表 List<Student> students = new List<Student> { new Student {LastName="Omelchenko", Scores= new List<int> {97, 72, 81, 60}}, new Student {LastName="O'Donnell", Scores= new List<int> {75, 84, 91, 39}}, new Student {LastName="Mortensen", Scores= new List<int> {88, 94, 65, 85}}, new Student {LastName="Garcia", Scores= new List<int> {97, 89, 85, 82}}, new Student {LastName="Beebe", Scores= new List<int> {35, 72, 91, 70}} }; // 定义Mongo语法的过滤器(注意字符串值要加单引号) FilterDefinition<Student> filter = "{ LastName: 'Omelchenko' }"; // 获取Student的Bson序列化器 var serializer = BsonSerializer.SerializerRegistry.GetSerializer<Student>(); // 渲染过滤器为BsonDocument var renderedFilter = filter.Render(serializer, BsonSerializer.SerializerRegistry); // 过滤内存列表 var matchingStudents = students.Where(student => renderedFilter.Matches(student.ToBsonDocument()) ).ToList();
方案二:将内存列表转为Mongo兼容的IQueryable后使用Inject
利用MongoDB驱动的LINQ扩展,将内存列表转为可识别Mongo过滤器的IQueryable:
using MongoDB.Bson; using MongoDB.Driver; using MongoDB.Driver.Linq; public class Student { public string LastName { get; set; } public List<int> Scores { get; set; } } // 初始化内存列表 List<Student> students = new List<Student> { new Student {LastName="Omelchenko", Scores= new List<int> {97, 72, 81, 60}}, new Student {LastName="O'Donnell", Scores= new List<int> {75, 84, 91, 39}}, new Student {LastName="Mortensen", Scores= new List<int> {88, 94, 65, 85}}, new Student {LastName="Garcia", Scores= new List<int> {97, 89, 85, 82}}, new Student {LastName="Beebe", Scores= new List<int> {35, 72, 91, 70}} }; // 将内存列表转为Mongo兼容的IQueryable var mongoQueryable = MongoDB.Driver.Linq.MongoQueryable.Create(students.AsQueryable()); // 定义过滤器(支持字符串语法或Builder方式) FilterDefinition<Student> filter = "{ LastName: 'Omelchenko' }"; // 或者用Builder:FilterDefinition<Student> filter = Builders<Student>.Filter.Eq(s => s.LastName, "Omelchenko"); // 应用过滤器并获取结果 var result = mongoQueryable.Where(s => filter.Inject()).ToList();
注意事项
- 字符串形式的过滤器必须符合Bson语法规则:字符串值需用单引号包裹,特殊字段名需用双引号包裹
- 确保实体类能被MongoDB的Bson序列化器正确处理,若有特殊字段可通过
[BsonElement]等特性配置映射 - 两种方案均支持复杂Mongo查询语法(如数组匹配、范围查询、逻辑组合等)
内容的提问来源于stack exchange,提问作者Francesco Borraccino
相关产品推荐
相关产品推荐

