You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在.NET 6 Web API的MongoDB单例类中实现Linq查询函数

.NET 6 Web API中MongoReader单例类新增Linq表达式查询方法

我在.NET 6 Web API中实现了MongoReader单例类,用于查询MongoDB集合。由于应用需要查询3个不同数据库的多个集合,现有方法仅支持接收FilterDefinition<T>参数,因此希望新增支持Linq表达式的查询方法,期望调用方式为:
await _reader.QueryCollectionLinqAsync<RandomClass>("DatabaseName.CollectionName", t => t.fieldName == fieldValue, limit, batchSize)

原MongoReader单例类代码

public class MongoReader
{
    private MongoClient _client;
    
    public MongoReader(string connectionString)
    {
        ConventionPack pack = new ConventionPack();
        pack.Add(new IgnoreExtraElementsConvention(true));
        ConventionRegistry.Register("My Solution Conventions", pack, t => true);

        _client = new MongoClient(connectionString);
    }
    
    public async Task<List<T>> QueryCollection<T>(string collection, FilterDefinition<T> filter,int limit = 50,int batchSize = 50) where T : class 
    {
        string[] collectionInformation = collection.Split('.');
        string collectionName = collectionInformation[1];
        string collectionDatabase = collectionInformation[0];

        List<T> list = new List<T> ();

        FindOptions<T> findOptions = new FindOptions<T>() { Limit = limit , BatchSize = batchSize };

        IAsyncCursor<T> cursor = await _client.GetDatabase(collectionDatabase).GetCollection<T>(collectionName).FindAsync(filter, findOptions);

        list = await cursor.ToListAsync();

        return list;
    }
}

最初非工作代码(使用Func<T,bool>参数)

使用Func<T,bool>作为Where条件参数时,无法调用ToListAsync()。原因在于Func<T,bool>是委托类型,会触发客户端内存过滤,无法被MongoDB的Linq提供器解析为数据库端执行的查询语句:

public async Task<List<T>> QueryCollection<T>(string collection, Func<T,bool> predicate, int limit = 50, int batchSize = 50) where T : class 
{
    string[] collectionInformation = collection.Split('.');
    string collectionName = collectionInformation[1];
    string collectionDatabase = collectionInformation[0];

    List<T> list = new List<T>();

    AggregateOptions options = new AggregateOptions() { BatchSize = batchSize };

    return await _client.GetDatabase(collectionDatabase).GetCollection<T>(collectionName).AsQueryable(options).Where(predicate).Take(limit).ToListAsync();
}

最终工作代码(改用Expression<Func<T,bool>>参数)

将参数类型改为Expression<Func<T,bool>>后问题解决,因为表达式树可以被MongoDB的Linq提供器解析为对应的MongoDB查询语句,在数据库端完成过滤操作:

public async Task<List<T>> QueryCollection<T>(string collection, Expression<Func<T,bool>> predicate, int limit = 50, int batchSize = 50) where T : class 
{
    string[] collectionInformation = collection.Split('.');
    string collectionName = collectionInformation[1];
    string collectionDatabase = collectionInformation[0];

    List<T> list = new List<T>();

    AggregateOptions options = new AggregateOptions() { BatchSize = batchSize };

    return await _client.GetDatabase(collectionDatabase).GetCollection<T>(collectionName).AsQueryable<T>(options).Where(predicate).ToListAsync();
}

内容的提问来源于stack exchange,提问作者Carlos Siestrup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 21:30:15