.net core WebAPI mongodb 动态查询

我想要实现efcode的expression功能,恰好mongodb.driver的Builders.Filter 支持&(and),|(or)

以下示例

  1. 安装依赖
MongoDB.Driver              2.27.0   2.27.0
  1. 定义model以及helper
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using System.Text.Json;

namespace MongoDBExpressionFilter.Models
{
    public class Person
    {
        [BsonId]
        [BsonRepresentation(BsonType.ObjectId)]
        public string Id { get; set; }
        [BsonElement("firstName")]
        public string FirstName { get; set; }
        [BsonElement("lastName")]
        public string LastName { get; set; }
        [BsonElement("age")]
        public int Age { get; set; }
    }




    public class MongoDbContext
    {
        private readonly IMongoDatabase _database;

        public MongoDbContext()
        {
            var client = new MongoClient("mongodb://ellis:ellischen@192.168.214.133:32000");
            _database = client.GetDatabase("ellis");
        }

        public IMongoCollection<Person> Persons => _database.GetCollection<Person>("Persons");
    }



    public static class FilterBuilder
    {
        public static FilterDefinition<Person> BuildFilter(Dictionary<string, JsonElement> filters)
        {
            var builder = Builders<Person>.Filter;
            var filter = builder.Empty; // Start with an empty filter

            foreach (var item in filters)
            {
                var fieldName = item.Key;
                var fieldValue = item.Value;



                switch (fieldValue.ValueKind)
                {
                    case JsonValueKind.String:
                        filter &= builder.Eq(fieldName, fieldValue.GetString());
                        break;
                    case JsonValueKind.Number:
                        if (fieldValue.TryGetInt32(out int intValue))
                        {
                            filter &= builder.Eq(fieldName, intValue);
                        }
                        else if (fieldValue.TryGetInt64(out long longValue))
                        {
                            filter &= builder.Eq(fieldName, longValue);
                        }
                        else if (fieldValue.TryGetDouble(out double doubleValue))
                        {
                            filter &= builder.Eq(fieldName, doubleValue);
                        }
                        break;
                    case JsonValueKind.True:
                    case JsonValueKind.False:
                        filter &= builder.Eq(fieldName, fieldValue.GetBoolean());
                        break;
                    // Add more cases as needed for different JsonValueKind types.
                    default:
                        throw new NotSupportedException($"Unsupported JSON value kind: {fieldValue.ValueKind}");
                }

            }

            return filter;
        }
    }

}

  1. 依赖注入
builder.Services.AddScoped<MongoDbContext>();
  1. 使用
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
using MongoDBExpressionFilter.Models;
using System.Text.Json;

namespace MongoDBExpressionFilter.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        private readonly MongoDbContext _context;

        public ValuesController(MongoDbContext context)
        {
            _context = context;
        }

        [HttpPost]
        public async Task<IActionResult> Filter([FromBody] Dictionary<string, JsonElement> filters)
        {
            var filter = FilterBuilder.BuildFilter(filters);
            var persons = await _context.Persons.Find(filter).ToListAsync();
            return Ok(persons);
        }
    }
}

源码

https://stackoverflow.com/questions/32227284/mongo-c-sharp-driver-building-filter-dynamically-with-nesting

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值