c# - 带有 C# : finding elements with custom predicate 的 MongoDB

标签 c# mongodb generics lambda mongodb-.net-driver

我有一个 MongoDB 数据库,其中包含一些集合,每个集合都存储特定类型的对象。我正在尝试实现一个通用选择函数,以根据类型对特定集合进行操作,如以下定义:

object[] Select<T>(Func<T, bool> condition)

例如,如果其中一个对象类型是 Person 类,我将实现以下内容:

object[] Select<T>(Func<T, bool> condition)
{
   if (typeof(T) == typeof(Person))
   {
        Func<Person, bool> f = (Person p) => 
        {
            return true;
        };
        return this.collectionPersons.AsQueryable().Where(p=>f(p)).ToArray();
    }
    else // ...
}

这段代码可以编译,但是当我尝试运行它时,我得到一个 System.ArgumentException

Additional information: Unsupported filter:        
Invoke(value(System.Func`2[Person,System.Boolean]), {document}).

在仔细阅读 API 文档后,我的印象是通常不可能使用抽象类型的 lambda 表达式(如上例),但只能使用 FilterDefinitionBuilder 比如Gt(), Eq()等。 我很好奇我是否理解正确,或者是否存在使用抽象谓词查询集合的可能性(我对 MongoDB C# 驱动程序还很陌生)。

最佳答案

当然,您可以使用 Lambda 表达式作为参数。驱动程序会将您的表达式转化为简单的过滤器,不可能翻译每个表达式,但如果可能的话,它会起作用。 我真的不明白你在样本中做了什么,你没有使用你的条件

您的函数不应采用 Func 而应采用 Expression 作为参数:

public static T[] Select<T>(IMongoCollection<T> collection,  
                             Expression<Func<T, bool>> condition)
{
    if (typeof(T) == typeof(Person))
    {
         return collection.AsQueryable().Where(condition).ToArray();
    }
    return null;
}

你可以用表达式来调用它:

var res = Select(this.collectionPersons, x => x.FirstName == "a3");

如果你只想查询所有项目,就像它看起来那样,你可以这样做:

return this.collectionPersons.Find(p=>true).ToArray();

而且您必须在 usings 中提及所有命名空间:

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Linq;
using MongoDB.Driver;
using MongoDB.Driver.Linq;

关于c# - 带有 C# : finding elements with custom predicate 的 MongoDB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42031543/

相关文章:

c# - 与 C# 的协方差

c# - 如何从数组创建随机数

ios - 如何使我的 ReferenceWritableKeyPath 类通用

java - 为什么 Google Gson.toJson 会丢失数据

c# - 初学者请求 Mysql 和 C# 帮助

c# - 如何在代码隐藏中获取回发参数值

mongodb - 蒙哥 : export all fields data from collection without specifying fields?

node.js - 如何使用 $filter 获取数组字段的过滤元素

angularjs - 当多个路径匹配时,Express 如何知道使用哪个 Router 路径?

c# - 泛型方法继承 : VS and Xamarin Studio yield different results; which is right?