【问题标题】:MongoDB .NET Driver - Convert lambda expressions to JSON objectMongoDB .NET 驱动程序 - 将 lambda 表达式转换为 JSON 对象
【发布时间】:2022-07-21 09:33:34
【问题描述】:

我需要将查询作为字符串而不是 lambda 表达式执行,因为我很难使用模拟框架为我的项目创建单元测试。

换句话说,我想修改我的IDatabase接口:

Interface IDatabase 
{
    IEnumerable<User> Find(Expression<Func<User, bool>> filter);
}

收件人:

Interface IDatabase 
{
    IEnumerable<User> Find(string query);
}

我已经有很多用表达式编写的查询。因此,我创建了这段代码来将表达式转换为 JSON 对象:

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

class Program
{

    // Example of a collection I store on my DB
    class User
    {
        public string _id { get; set; }

        public string Name { get; set; }

        public DateTime DateCreated { get; set; }
    }

    // Main method
    public static void Main()
    {
        var json = ExpressionToJson<User>(x => x.Name.Contains("Tono") && x.DateCreated < DateTime.UtcNow);

        // outputs:
        // { "Name" : /Tono/s, "DateCreated" : { "$lt" : ISODate("2022-01-21T01:21:27.975Z") } }
        Console.WriteLine(json);

    }

    /// <summary>
    ///     Method that will convert an expression to a string
    /// </summary>
    public static string ExpressionToJson<T>(Expression<Func<T, bool>> filter)
    {
        MongoClient MongoClient = new MongoClient();

        var db1 = MongoClient.GetDatabase("DoesNotMatter");

        var collection = db1.GetCollection<T>("DoesNotMatter");

        var query = collection.Find(filter);

        var json = query.ToString();

        if (string.IsNullOrEmpty(json))
            return "{}";

        // json should look something like this
        // find({ "Name" : /Tono/s, "DateCreated" : { "$lt" : ISODate("2022-01-21T01:11:47.772Z") } })

        // remove the find( at the beginning and last parenthesis
        if (json.StartsWith("find("))
            return json.Substring(5, json.Length - 6);

        throw new NotImplementedException("Did serializer changed?");
    }

}

如你所见,这段代码可以转换表达式

x => x.Name.Contains("Tono") && x.DateCreated < DateTime.UtcNow

转 JSON

{ "Name" : /Tono/s, "DateCreated" : { "$lt" : ISODate("2022-01-21T01:24:38.628Z") } }

如何简化ExpressionToJson 方法?如果我可以避免创建MongoClient 的实例,然后是数据库的实例,然后是IMongoCollection&lt;TDocument&gt; 的实例,以便在我需要的时候序列化表达式,那就太棒了。

【问题讨论】:

    标签: c# json mongodb mongodb-.net-driver


    【解决方案1】:

    或许,你可以写一个IMongoCollection扩展方法,采用IFindFluent&lt;T, T&gt;.Filter.Render(类似于this question)生成JSON格式的过滤查询。

    public static class IMongoCollectionExtensions
    {
        public static string ExpressionToJson<T>(this IMongoCollection<T> collection, Expression<Func<T, bool>> filter)
        {
            var query = collection.Find(filter);
    
            return query.Filter.Render(
                collection.DocumentSerializer,
                collection.Settings.SerializerRegistry
            ).ToJson();
        }
    }
    
    var jsonQuery = collection.ExpressionToJson<User>(x => x.Name.Contains("Tono")
        && x.DateCreated < DateTime.UtcNow);
    

    输出

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多