Update Mongodb

This commit is contained in:
sunkaixuan
2025-05-04 21:09:25 +08:00
parent 03cb3ee32b
commit f45f9975d8
5 changed files with 67 additions and 57 deletions

View File

@@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq; using MongoDB.Bson;
using Newtonsoft.Json.Linq;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq.Expressions; using System.Linq.Expressions;
@@ -10,19 +11,22 @@ namespace SqlSugar.MongoDbCore
{ {
private MongoNestedTranslatorContext context; private MongoNestedTranslatorContext context;
public ExpressionVisitorContext visitorContext; public ExpressionVisitorContext visitorContext;
public ExpressionVisitor(MongoNestedTranslatorContext context, ExpressionVisitorContext expressionVisitorContext) public ExpressionVisitor(MongoNestedTranslatorContext context, ExpressionVisitorContext expressionVisitorContext)
{ {
this.context = context; this.context = context;
this.visitorContext = expressionVisitorContext; this.visitorContext = expressionVisitorContext;
} }
public ExpressionVisitor(MongoNestedTranslatorContext context) public ExpressionVisitor(MongoNestedTranslatorContext context)
{ {
this.context = context; this.context = context;
} }
public JToken Visit(Expression expr) public BsonValue Visit(Expression expr)
{ {
expr = MongoDbExpTools.RemoveConvert(expr); expr = MongoDbExpTools.RemoveConvert(expr);
switch (expr) switch (expr)
{ {
case BinaryExpression binary: case BinaryExpression binary:
@@ -34,7 +38,7 @@ namespace SqlSugar.MongoDbCore
case UnaryExpression unary: case UnaryExpression unary:
return this.Visit(unary); return this.Visit(unary);
case LambdaExpression lambda: case LambdaExpression lambda:
return this.Visit((lambda as LambdaExpression).Body); return this.Visit(lambda.Body);
default: default:
throw new NotSupportedException($"Unsupported expression: {expr.NodeType}"); throw new NotSupportedException($"Unsupported expression: {expr.NodeType}");
} }

View File

@@ -3,15 +3,15 @@ using System.Collections.Generic;
using System.Text; using System.Text;
using System.Linq.Expressions; using System.Linq.Expressions;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using MongoDB.Bson;
namespace SqlSugar.MongoDbCore namespace SqlSugar.MongoDbCore
{ {
public static class MongoNestedTranslator public static class MongoNestedTranslator
{ {
public static JObject Translate(Expression expr, MongoNestedTranslatorContext context) public static BsonDocument Translate(Expression expr, MongoNestedTranslatorContext context)
{ {
return (JObject)new ExpressionVisitor(context).Visit(expr); return (BsonDocument)new ExpressionVisitor(context).Visit(expr);
} }
} }
} }

View File

@@ -1,4 +1,5 @@
using MongoDB.Driver; using MongoDB.Bson;
using MongoDB.Driver;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -16,7 +17,7 @@ namespace SqlSugar.MongoDbCore
_context = context; _context = context;
} }
public JToken Extract(BinaryExpression expr) public BsonDocument Extract(BinaryExpression expr)
{ {
if (expr.NodeType == ExpressionType.AndAlso || expr.NodeType == ExpressionType.OrElse) if (expr.NodeType == ExpressionType.AndAlso || expr.NodeType == ExpressionType.OrElse)
{ {
@@ -26,25 +27,26 @@ namespace SqlSugar.MongoDbCore
return FieldComparisonExpression(expr); return FieldComparisonExpression(expr);
} }
private JToken LogicalBinaryExpression(BinaryExpression expr) private BsonDocument LogicalBinaryExpression(BinaryExpression expr)
{ {
string logicOp = expr.NodeType == ExpressionType.AndAlso ? "$and" : "$or"; string logicOp = expr.NodeType == ExpressionType.AndAlso ? "$and" : "$or";
var left = new ExpressionVisitor(_context).Visit(expr.Left); var left = new ExpressionVisitor(_context).Visit(expr.Left);
var right = new ExpressionVisitor(_context).Visit(expr.Right); var right = new ExpressionVisitor(_context).Visit(expr.Right);
var arr = new JArray(); var arr = new BsonArray();
AddNestedLogic(arr, left, logicOp); AddNestedLogic(arr, left, logicOp);
AddNestedLogic(arr, right, logicOp); AddNestedLogic(arr, right, logicOp);
return new JObject { [logicOp] = arr }; return new BsonDocument { { logicOp, arr } };
} }
private void AddNestedLogic(JArray arr, JToken token, string logicOp) private void AddNestedLogic(BsonArray arr, BsonValue token, string logicOp)
{ {
if (token is JObject obj && obj.TryGetValue(logicOp, out var nested) && nested is JArray nestedArr) if (token is BsonDocument obj && obj.Contains(logicOp))
{ {
arr.Merge(nestedArr); var nestedArr = obj[logicOp].AsBsonArray;
arr.AddRange(nestedArr);
} }
else else
{ {
@@ -52,26 +54,29 @@ namespace SqlSugar.MongoDbCore
} }
} }
private JToken FieldComparisonExpression(BinaryExpression expr) private BsonDocument FieldComparisonExpression(BinaryExpression expr)
{ {
var left = new ExpressionVisitor(_context, new ExpressionVisitorContext()); var left = new ExpressionVisitor(_context, new ExpressionVisitorContext());
var right = new ExpressionVisitor(_context, new ExpressionVisitorContext()); var right = new ExpressionVisitor(_context, new ExpressionVisitorContext());
JToken field = left.Visit(expr.Left); BsonValue field = left.Visit(expr.Left);
JToken value = right.Visit(expr.Right); BsonValue value = right.Visit(expr.Right);
var leftIsMember = false; bool leftIsMember = false;
var rightIsMember = false; bool rightIsMember = false;
if (left?.visitorContext?.ExpType == typeof(MemberExpression)) if (left?.visitorContext?.ExpType == typeof(MemberExpression))
{ {
leftIsMember = true; leftIsMember = true;
} }
if (right?.visitorContext?.ExpType == typeof(MemberExpression)) if (right?.visitorContext?.ExpType == typeof(MemberExpression))
{ {
rightIsMember = true; rightIsMember = true;
} }
string op = expr.NodeType switch string op = expr.NodeType switch
{ {
ExpressionType.Equal => value.Type == JTokenType.Null ? "$eq" : null, ExpressionType.Equal => value.IsBsonNull ? "$eq" : null,
ExpressionType.NotEqual => value.Type == JTokenType.Null ? "$ne" : "$ne", ExpressionType.NotEqual => value.IsBsonNull ? "$ne" : "$ne",
ExpressionType.GreaterThan => "$gt", ExpressionType.GreaterThan => "$gt",
ExpressionType.GreaterThanOrEqual => "$gte", ExpressionType.GreaterThanOrEqual => "$gte",
ExpressionType.LessThan => "$lt", ExpressionType.LessThan => "$lt",
@@ -79,14 +84,14 @@ namespace SqlSugar.MongoDbCore
_ => throw new NotSupportedException($"Unsupported binary op: {expr.NodeType}") _ => throw new NotSupportedException($"Unsupported binary op: {expr.NodeType}")
}; };
if (op == null&&leftIsMember&&rightIsMember==false) if (op == null && leftIsMember && !rightIsMember)
return new JObject { [field.ToString()] = value }; return new BsonDocument { { field.ToString(), value } };
else if (op == null && rightIsMember && leftIsMember == false) else if (op == null && rightIsMember && !leftIsMember)
return new JObject { [value.ToString()] = field }; return new BsonDocument { { value.ToString(), field } };
return new JObject return new BsonDocument
{ {
[field.ToString()] = new JObject { [op] = value } { field.ToString(), new BsonDocument { { op, value } } }
}; };
} }
} }

View File

@@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq; using MongoDB.Bson;
using Newtonsoft.Json.Linq;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq.Expressions; using System.Linq.Expressions;
@@ -10,32 +11,36 @@ namespace SqlSugar.MongoDbCore
{ {
MongoNestedTranslatorContext _context; MongoNestedTranslatorContext _context;
ExpressionVisitorContext _visitorContext; ExpressionVisitorContext _visitorContext;
public FieldPathExtractor(MongoNestedTranslatorContext context, ExpressionVisitorContext visitorContext) public FieldPathExtractor(MongoNestedTranslatorContext context, ExpressionVisitorContext visitorContext)
{ {
_context = context; _context = context;
_visitorContext = visitorContext; _visitorContext = visitorContext;
} }
public string Extract(Expression expr) public BsonValue Extract(Expression expr)
{ {
var oldExp = expr; var oldExp = expr;
var oldMember = expr as MemberExpression; var oldMember = expr as MemberExpression;
var parts = new Stack<string>(); var parts = new Stack<string>();
while (expr is MemberExpression member) while (expr is MemberExpression member)
{ {
parts.Push(member.Member.Name); parts.Push(member.Member.Name);
expr = member.Expression!; expr = member.Expression!;
} }
if (expr is ConstantExpression constantExpression) if (expr is ConstantExpression constantExpression)
{ {
var value = ExpressionTool.GetMemberValue(oldMember.Member, oldExp); var value = ExpressionTool.GetMemberValue(oldMember.Member, oldExp);
return MongoDbExpTools.CustomToString(value); return BsonValue.Create(value);
} }
if (_visitorContext != null) if (_visitorContext != null)
{ {
_visitorContext.ExpType = typeof(MemberExpression); _visitorContext.ExpType = typeof(MemberExpression);
} }
return string.Join(".", parts); return BsonValue.Create(string.Join(".", parts));
} }
} }

View File

@@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq; using MongoDB.Bson;
using Newtonsoft.Json.Linq;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq.Expressions; using System.Linq.Expressions;
@@ -9,20 +10,15 @@ namespace SqlSugar.MongoDbCore
public class ValueExtractor public class ValueExtractor
{ {
MongoNestedTranslatorContext _context; MongoNestedTranslatorContext _context;
public ValueExtractor(MongoNestedTranslatorContext context, ExpressionVisitorContext visitorContext) public ValueExtractor(MongoNestedTranslatorContext context, ExpressionVisitorContext visitorContext)
{ {
_context = context; _context = context;
} }
public JToken Extract(ConstantExpression expr)
{
return JToken.FromObject(expr.Value);
}
public static JToken GetValue(Expression expr) public BsonValue Extract(ConstantExpression expr)
{ {
var lambda = Expression.Lambda(expr); return BsonValue.Create(expr.Value);
var compiled = lambda.Compile();
return JToken.FromObject(compiled.DynamicInvoke());
} }
} }
} }